home *** CD-ROM | disk | FTP | other *** search
/ MacWorld: Conference & Expo 2005 / Macworld Conference and Expo - Documentation CD-ROM (2004).iso / mac / Adobe Reader 6.0 / Adobe Reader 6.0.app / Contents / MacOS / Updater / bootstrap.js < prev   
Text File  |  2004-01-30  |  94KB  |  2,742 lines

  1. //
  2. // All scripts (master, data, code, ui, maintainance, etc) should obey the
  3. // following conventions:
  4. //
  5. // -- each script can define one and only one object.  eval() returns the
  6. // result of evaluating the last statement of the script.  therefore, the
  7. // last statement of all script should simply be the script obj.
  8. // 
  9. // -- has a "version" key
  10. // 
  11. // --  more to be added
  12.  
  13. // constants used during evaluation for dialog descriptions
  14. var isMac = new Boolean(updater.app.platform.substr(0,3) == "MAC");
  15. var isWin = new Boolean(updater.app.platform.substr(0,3) == "WIN");
  16. var isReader = new Boolean((updater.app.viewerType.substr(0,6) == "Reader"));
  17.  
  18. var nextCheckText = (updater.app.getUpdaterString("IDS_PREFS_PANEL_NEXTCHECK"));
  19. var manualNextCheck = (updater.app.getUpdaterString("IDS_PREFS_PANEL_MANUALNEXTCHECK"));
  20. var checkForUpdatesText = (updater.app.getUpdaterString("IDS_PREFS_PANEL_CHECKTXT"));
  21. var updateAcrobatNowText = (updater.app.getUpdaterString("IDS_UPDATE_ACROBAT_NOW"));
  22. var updateReaderNowText = (updater.app.getUpdaterString("IDS_UPDATE_READER_NOW"));
  23. var updateNotificationBtn = (updater.app.getUpdaterString("IDS_PREFS_PANEL_VIEW_NOTIFS"));
  24. var showConfirmDlgText = (updater.app.getUpdaterString("IDS_UPDATE_AUTO_CONF_TXT"));
  25. var displayStartupNotifDlgText = (updater.app.getUpdaterString("IDS_UPDATE_SHOW_NOTIF_TXT"));
  26.  
  27. // calcuate width of the button 
  28. var gStaticTextWidth = 8;
  29. //var gUpdateNowWidth =  (gStaticTextWidth * Math.max(updateAcrobatNowText.length, updateReaderNowText.length));
  30. var gUpdateNowWidth = (gStaticTextWidth * updateNotificationBtn.length);
  31.  
  32. var ScriptObj = {
  33.  
  34.     version:"0.10",
  35.  
  36.     prodConfigToURLMap: {
  37.       "Exchange-Pro": "pro",
  38.       "Exchange" : "std",
  39.       "Reader" : "rdr"
  40.     },
  41.  
  42.     scriptRootTemplate: "_PRODCONF_/_PLATFORM_/_LANG_/",
  43.  
  44.     getScriptRootURL: function()
  45.     {
  46.       var prod, platform, lang;
  47.       
  48.       prod = this.prodConfigToURLMap[updater.app.viewerType];
  49.       this.assert(prod.length > 0, "Invalid Product Config");
  50.       
  51.       platform = updater.app.platform.toLowerCase();
  52.  
  53.       var lang;
  54.  
  55.       var tier = this.getAppTier();
  56.  
  57.       // user is in cross tier config
  58.       if (tier.toLowerCase() == "all") { lang = "all"; }
  59.       else if (tier.toLowerCase() == "enu") { lang = "enu"; }
  60.       else { lang = this.getDefLangForTier(tier).toLowerCase(); }
  61.  
  62.       var urlext = new String(this.scriptRootTemplate);
  63.  
  64.       urlext = urlext.replace(/_PRODCONF_/, prod);
  65.       urlext = urlext.replace(/_PLATFORM_/, platform);
  66.       urlext = urlext.replace(/_LANG_/, lang);
  67.       
  68.       updater.console.println("url ext = " + urlext);
  69.       
  70.       return updater.scriptRootURL + urlext;
  71.     },
  72.     
  73.     getDSURL: function()
  74.     {
  75.         var dsfile = "DataScript.js";
  76.         var ret = this.getScriptRootURL() + dsfile;
  77.         return ret;
  78.     },
  79.  
  80.  
  81.     //
  82.     // The App Tier and Language  API
  83.     //
  84.     // The Language code
  85.     //
  86.     //      {"DEU", "de-DE"},
  87.     //         {"ESP", "es-ES"},
  88.     //         {"FRA", "fr-FR"},
  89.     //         {"ITA", "it-IT"},
  90.     //         {"JPN", "ja-JP"},
  91.     //         {"NLD", "nl-NL"},
  92.     //         {"SVE", "sv-SE"},
  93.     //         {"SUO", "fi-FI"},
  94.     //         {"NOR", "no-NO"},
  95.     //         {"NON", "no-NO"},
  96.     //         {"DAN", "da-DK"},
  97.     //         {"KOR", "ko-KR"},
  98.     //         {"PTB", "pt-BR"},
  99.     //         {"CHS", "zh-CN"},
  100.     //         {"CHT", "zh-TW"},
  101.     //         {"ENU", "en-US"}
  102.     //
  103.   
  104.     // language code id to description
  105.     LangToDescMap:
  106.     {
  107.     "ENU" : "English",
  108.     "JPN" : "Japanese",
  109.     "CHT" : "Chinese Traditional",
  110.     "CHS" : "Chinese Simplified",
  111.     "KOR" : "Korean",
  112.     "FRA" : "French",
  113.     "DEU" : "German",
  114.     "PTB" : "Portuguese Brazil",
  115.     "ITA" : "Italian",
  116.     "NLD" : "Dutch",
  117.     "ESP" : "Spanish",
  118.     "SVE" : "Swedish",
  119.     "DAN" : "Danish",
  120.     "SUO" : "Finish",
  121.     "NOR" : "Norwegian",
  122.     "HEB" : "Hebrew",
  123.     "ARA" : "Arabic"
  124.     },
  125.  
  126.     // Map either ISO4Char or RFC1766 to language code id
  127.     CountryToLangMap: 
  128.     {
  129.     "en"    : "ENU",
  130.     "en-us" : "ENU",
  131.     "ja"    : "JPN",
  132.     "ja-jp" : "JPN",
  133.     "zh-tw" : "CHT",
  134.     "zh-cn" : "CHS",
  135.     "ko"    : "KOR", 
  136.     "ko-kr" : "KOR",
  137.     "fr"    : "FRA",
  138.     "fr-fr" : "FRA",
  139.     "de"    : "DEU",
  140.     "de-de" : "DEU",
  141.     "pt-br" : "PTB",
  142.     "it"    : "ITA",
  143.     "it-it" : "ITA",
  144.     "nl"    : "NLD",
  145.     "nl-nl" : "NLD",
  146.     "es"    : "ESP",
  147.     "es-sp" : "ESP",
  148.     "sv"    : "SVE",
  149.     "sv-se" : "SVE",
  150.     "da"    : "DAN",
  151.     "da-dk" : "DAN",
  152.     "fi"    : "SUO",
  153.     "fi-fi" : "SUO",
  154.     "no"    : "NOR",
  155.     "no-no" : "NOR",
  156.     "he"    : "HEB",
  157.     "he-il" : "HEB",
  158.     "ar"    : "ARA",
  159.     "ar-ae" : "ARA"
  160.     },
  161.  
  162.     // TODO: need to update the tier map
  163.     // Map Tier to lang in lang code id
  164.     TierToLangsMap:
  165.     {
  166.     "EFG"  : ["FRA", "DEU"],
  167.     "EFGJ" : ["FRA", "DEU", "JPN"],
  168.     "JPN"  : ["JPN"],
  169.     "CCK"  : ["CHT", "CHS", "KOR"],
  170.     "DDS"  : ["DAN", "NLD", "ESP"],
  171.     "NF"   : ["NOR", "SUO"],
  172.     "SIP"  : ["SVE", "ITA", "PTB"]
  173.     },
  174.  
  175.     // if the app is in a tier BUT running in ENU, which is always available,
  176.     // then we need to have a default lang for the tier so that we know where
  177.     // to fetch the correct DataScript from
  178.     getDefLangForTier: function(tier) {
  179.       var m = this.TierToLangsMap;
  180.       for (var i in this.TierToLangsMap) {
  181.         if (i.toLowerCase() == tier.toLowerCase()) {
  182.           return m[i][0]; // the first element in array is the default lang
  183.           }
  184.         }
  185.       updater.MasterScript.assert(false, "Invalid Tier: " + tier);
  186.       return "ENU";  // just in case something really bad happens
  187.     },
  188.  
  189.     getAppLang: function() {
  190.       if ( ! updater.MasterScript.PropertyIsDefined(updater, "appLang") ||
  191.            updater.appLang == null ) 
  192.         {
  193.         updater.appLang = updater.app.language;
  194.         }
  195.       return updater.appLang;
  196.     },
  197.   
  198.     // Returns
  199.     // 1. ENU iff ENU is the only lang the app has
  200.     // 2. ALL if app has cross tier lang res
  201.     // 3. one of the key in TierToLangsMap reflecting the tier app is in
  202.     getAppTier: function() {
  203.  
  204.       if ( updater.MasterScript.PropertyIsDefined(updater, "appTier") &&
  205.            updater.appTier != null ) {
  206.         return updater.appTier;
  207.         }
  208.  
  209.       updater.console.println("app is running with lang = " + this.getAppLang());
  210.     
  211.       // determine tier
  212.       var res;
  213.       try {
  214.         res = this.getLangRes();
  215.         }
  216.       catch (e) {
  217.         updater.console.println("Exception calling getLangRes()" + e);
  218.         this.assert(false, "  getLangRes() exception");
  219.         updater.console.println("  defaulting res to ENU");
  220.         res = new Array();
  221.         res[0] = "ENU";
  222.         }
  223.     
  224.       updater.console.println("app has follow lang resources = " + res);
  225.  
  226.       if (res.length == 1) { 
  227.         // if the app has ONLY single lang has, it MUST be ENU
  228.         updater.MasterScript.assert(res[0] == "ENU", "Single Lang res MUST be ENU");
  229.         updater.appTier = res[0];
  230.         return res[0]; 
  231.         }
  232.     
  233.       var dup = {};  // used as a boolean bitmap
  234.       var t = Array();  // list of tiers
  235.       
  236.       // narrow down to Tiers given all the res available
  237.       for ( var i in res ) {
  238.         // skip ENU cause all config has ENU
  239.         if (res[i] == "ENU") { continue; }
  240.  
  241.         var tier = this.mapLangToTier(res[i]);
  242.         if ( ! updater.MasterScript.PropertyIsDefined(dup, tier) ) {
  243.           dup[tier] = true;
  244.           t.push(tier);
  245.           }
  246.         // updater.MasterScript.DumpObject(dup, "dup", true);
  247.         }
  248.       
  249.       updater.console.println("app is in tier = " + t);
  250.       
  251.       if (t.length == 1) {
  252.         updater.appTier = t[0];
  253.         }
  254.       else {
  255.         updater.console.println("app is in Multi-Tier = " + t);
  256.         updater.appTier = "ALL";
  257.         }
  258.       return updater.appTier;
  259.     },
  260.     
  261.     mapLangToTier: function(lang) {
  262.       var m = this.TierToLangsMap;
  263.       for ( var tier in m ) {
  264.         var langs = m[tier];
  265.         for ( var i in langs) {
  266.           if ( lang.toLowerCase() == langs[i].toLowerCase() ) return tier;
  267.           }
  268.         }
  269.       updater.MasterScript.assert(false, "Input Lang invalid: " + lang);
  270.     },
  271.  
  272.   
  273.     // return array of resources in Country Code app has.
  274.     // ENU MUST always be in the array.
  275.     getLangRes: function() {
  276.       var langRet = new Array();
  277.  
  278.       if (updater.app.platform == "WIN") {
  279.         var type = updater.app.viewerType;
  280.         var winLangFileBase;
  281.         if ( type == "Reader" ) {
  282.            winLangFileBase = "RdLang32";
  283.           }
  284.         else {
  285.           winLangFileBase = "ExLang32";
  286.           }
  287.         var avSpCat = updater.fileSys.AVSpecialCategory;
  288.         var avSpFold = updater.fileSys.AVSpecialFolder;
  289.       
  290.         var resRoot = updater.fileSys.GetSpecialFolder(avSpCat["kAVSCApp"], 
  291.                                                        avSpFold["kAVSFRoot"]);
  292.         updater.console.println("Enum items in mdPath: " + resRoot.mdPath);
  293.         var files = updater.fileSys.enumFolderItems(resRoot.mdPath);
  294.         var idx = 0;
  295.  
  296.         // win always have ENU
  297.         langRet[idx++] = "ENU";
  298.       
  299.         for (var i = 0; i < files.length; i++) {
  300.           //updater.console.println(" file = " + files[i].fileNameBase + "   ext = " + files[i].fileNameExt);
  301.         
  302.           if( files[i].isExistingFile  &&
  303.               (this.getFileNameBase(files[i].fileName).toLowerCase() 
  304.                == winLangFileBase.toLowerCase() ) )
  305.             {
  306.             var lcode = this.getFileNameExt(files[i].fileName).toLowerCase();
  307.             updater.console.println(" lcode = " + lcode);
  308.             if ( typeof(lcode) != "undefined" ) { langRet[idx++] = lcode; }
  309.             }
  310.           }
  311.         }
  312.       else if (updater.app.platform == "MAC") {
  313.         var macLangFileExt = "lproj";
  314.       
  315.         var avSpCat = updater.fileSys.AVSpecialCategory;
  316.         var avSpFold = updater.fileSys.AVSpecialFolder;
  317.       
  318.         var resRoot = updater.fileSys.GetSpecialFolder(avSpCat["kAVSCApp"], 
  319.                                                        avSpFold["kAVSFRoot"]);
  320.         // no special folder defined to access lang resource folder.
  321.         // manually create the path from app root:
  322.         //    /Acrobat 6.0.app/Contents/MacOS/
  323.         // -->/Acrobat 6.0.app/Contents/Resources/
  324.         var dip = new String(resRoot.diPath);
  325.         var resPath = dip.replace(/MacOS/, "Resources");
  326.         updater.console.println("Enum items in diPath: " + resPath);
  327.         var files = updater.fileSys.enumFolderItems(resPath, true);
  328.         var idx = 0;
  329.       
  330.         for (var i = 0; i < files.length; i++) {
  331.           //updater.console.println(" file = " + files[i].fileNameBase + "   ext = " + files[i].fileNameExt);
  332.         
  333.           if( files[i].isExistingFolder  &&
  334.               (this.getFileNameExt(files[i].fileName).toLowerCase() 
  335.                == macLangFileExt.toLowerCase() ) )
  336.             {
  337.             var cnt = this.getFileNameBase(files[i].fileName).toLowerCase();
  338.             // Mac may use underscore instead of dash in country lang code 
  339.             // ie: "zh_cn" instead of "zh-cn".  
  340.             // replace it with dash.
  341.             cnt = cnt.replace(/_/, "-");
  342.             var lcode = this.CountryToLangMap[cnt];
  343.             updater.console.println(" cnt   = " + cnt);
  344.             updater.console.println(" lcode = " + lcode);
  345.             this.assert(lcode.length > 0, "Cannot find " + cnt + " in CountryToLangMap");
  346.             if ( typeof(lcode) != "undefined" ) { langRet[idx++] = lcode; }
  347.             }
  348.           }
  349.         }
  350.       else {
  351.         this.assert(false, "Unsupported platform : " + updater.app.platform);
  352.         return null;
  353.         }
  354.     
  355.       return langRet;
  356.     },
  357.  
  358.     // base.ext
  359.     getFileNameBase: function(fn) {
  360.       var sep = fn.indexOf(".");
  361.       if (sep == -1) return fn;
  362.       return fn.substring(0, sep);
  363.     },
  364.  
  365.     // base.ext
  366.     getFileNameExt: function(fn) {
  367.       var sep = fn.indexOf(".");
  368.       if (sep == -1) return "";
  369.       return fn.substring(sep + 1, fn.length);
  370.     },
  371.  
  372.  
  373.     // pop a dialog and return true if restart pending.
  374.     checkPendingRestart: function(silent) 
  375.     {
  376.       var restartPending;
  377.       
  378.       if ( typeof(updater["restartPending"]) != "undefined") {
  379.         updater.console.println("===> App Restart Pending!  Skip Running Updater");
  380.         restartPending = updater.restartPending;
  381.         
  382.         // need restarting Acrobat...  
  383.         if (! silent) {
  384.           var title = updater.app.getUpdaterString("uisJSNeedRestartTitle");
  385.           var type = updater.app.viewerType;
  386.           var infoMsg;
  387.           if ( type == "Reader" ) {
  388.             infoMsg = updater.app.getUpdaterString("uisJSNeedRestartTxtRdr");
  389.             }
  390.           else {
  391.             infoMsg = updater.app.getUpdaterString("uisJSNeedRestartTxtVwr");
  392.             }
  393.           updater.app.alert({nIcon:3, nType:0, cTitle:title, cMsg:infoMsg});  
  394.           }
  395.         }
  396.       else {
  397.         restartPending = false;
  398.         }
  399.       return restartPending;
  400.     },
  401.  
  402.     // ALL MasterScript entry point MUST call init() before proceeding.
  403.     // if init() returns false, caller should exit and not proceed.
  404.     init: function(silent)
  405.     {
  406.       updater.console.println("MasterScript init() - silent = " + silent);
  407.       
  408.       if (updater.app.getUpdateDisabled()) {
  409.         updater.console.println("   Updater Disabled!!");
  410.         return false;
  411.       }
  412.       
  413.       // checkPendingRestart is the only init func for now.
  414.       // may have more MasterScript global init func later.
  415.       var ret = this.checkPendingRestart(silent);
  416.  
  417.       // don't cont if restart pending
  418.       var toCont = !ret;
  419.  
  420.       updater.console.println("MasterScript init() - to continue = " + toCont);
  421.       return (toCont);
  422.     },
  423.  
  424.     //
  425.     // Main Entry point for doing manual or auto updates
  426.     //
  427.     // set force to true for manual update, otherwise, it determines if it is
  428.     // time to update for the auto update case
  429.     // 
  430.     entryPoint: function(force)
  431.     {
  432.       force ? this.ManualUpdateAsync() : this.AutoUpdateAsync();
  433.     },
  434.  
  435.     // 
  436.     // utils function 
  437.     //
  438.     PropertyIsDefined: function( obj, propName )
  439.     {
  440.         var ret = (typeof( obj[ propName ] ) != "undefined");
  441.         // updater.console.println("PropertyIsDefined returns " + ret + " for " + propName);
  442.         return ret;
  443.     },
  444.  
  445.     DumpStrObj: function (obj) {
  446.       // updater.console.println("  ---- DumpStrObj -----");
  447.       updater.console.println("  obj.length = " + obj.length);
  448.       for (var i = 0; i < obj.length; i++) {
  449.         updater.console.println("  charcode obj[" + i + "] = " + obj.charCodeAt(i));
  450.       }
  451.       // updater.console.println("  ---- DumpStrObj End -----");
  452.     },
  453.     
  454.     // improve it to dump recursively later if i have time
  455.     DumpObject: function (obj, str, vals) {
  456.       if (! str ) str = "";
  457.       else str = str + " ";
  458.       str += "(" + obj + ") [" + typeof(obj) + "]\n";
  459.       for (var p in obj) {
  460.         str += "  " + p + ( vals ? ": " + obj[p] : "") + "\n";
  461.       }
  462.       updater.console.println(str);
  463.     },
  464.  
  465.     DumpArray: function (array, str) {
  466.       if (! str ) str = "";
  467.       else str = str + " ";
  468.       str += "(" + array + ") [" + typeof(array) + "]\n{ ";
  469.       for( var i = 0;  i < array.length;  i++ ) {
  470.         str += array[i] + ( i < array.length - 1 ? ", " : " }" );
  471.       }
  472.       updater.console.println(str);
  473.     },
  474.  
  475.     GetFunctionName: function(f) {
  476.       var name = f.toString().match(/(function .*\))/)[1];
  477.  
  478.       if ((name == null) || (name.length == 0))
  479.         name = 'anonymous';
  480.  
  481.       return name;
  482.     },
  483.  
  484.     StackTrace: function() 
  485.     {
  486.       var ret = '';
  487.       for (var i = arguments.callee.caller; i != null; i = i.caller) {
  488.         if (i) {
  489.           ret += '> ' + this.GetFunctionName(i) + '\n';
  490.         }
  491.         // if (i.caller == i) {
  492.         //           ret += '*';
  493.         //           break;
  494.         //         }
  495.       }
  496.       return ret;
  497.     },
  498.  
  499.     assert: function(cond, details) {
  500.       if (!cond) {
  501.         var msg = "!!!!! Assert failure ";
  502.         if (details) {
  503.           msg = msg + " - " + details;
  504.         }
  505.         if (arguments.callee.caller != null) {
  506.           msg = msg + "in " 
  507.                 + this.GetFunctionName(arguments.callee.caller)
  508.                 + ")";
  509.         }
  510.         msg = msg + "\n" + this.StackTrace();
  511.         updater.console.println(msg);
  512.       }
  513.     },
  514.  
  515.  
  516.     //
  517.     // convert a string in generalized ASN1 time format to JS Date Object
  518.     // returns null if conversion failed.  (it only support UTC as timezone.
  519.     // cannot convert between timezones yet)
  520.     // 
  521.     // eg:
  522.     // http last mod date:
  523.     // Date: Thu, 07 Nov 2002 10:09:38 GMT
  524.     // GEN_ASN1 eg1:
  525.     // "20021107061101Z"
  526.     //  012345678901234
  527.     // 
  528.     // GEN_ASN1 eg2:
  529.     // "20021107061101.27Z"
  530.     // 
  531.     // GEN_ASN1 eg3:
  532.     // "20021107061101.27-0200"
  533.     //
  534.     GenASN1ToDate: function (str) {
  535.  
  536.       var year, month, day, hours, mins, secs, ms, timezone;
  537.       var timeStr = new String(str);
  538.  
  539.       // has to be at least 14 or more chars
  540.       if (timeStr.length < 14) { return null; }
  541.  
  542.       year  = timeStr.substring(0 , 4);
  543.       month = timeStr.substring(4 , 6);
  544.       // zero based month used in JS Date
  545.       month = month - 1;
  546.       day   = timeStr.substring(6 , 8);
  547.       hours = timeStr.substring(8 , 10);
  548.       mins  = timeStr.substring(10, 12);
  549.       secs  = timeStr.substring(12, 14);
  550.  
  551. //       updater.console.println(year);
  552. //       updater.console.println(month);
  553. //       updater.console.println(day);
  554. //       updater.console.println(hours);
  555. //       updater.console.println(mins);
  556. //       updater.console.println(secs);
  557.  
  558.       
  559.       // if more than 14 chars, ms and/or timezone may be present
  560.       ms = 0; 
  561.       timezone = "Z";
  562.  
  563.       if (timeStr.length > 14) {
  564.         var plus, minus, zee, dot;
  565.         dot =  timeStr.indexOf(".", 14);
  566.         plus = timeStr.indexOf("+", 14);
  567.         minus = timeStr.indexOf("-", 14);
  568.         zee = timeStr.indexOf("Z", 14);
  569.  
  570. //         updater.console.println("dot = " + dot);        
  571. //         updater.console.println("plus = " + plus);
  572. //         updater.console.println("minus = " + minus);
  573. //         updater.console.println("zee = " + zee);
  574.  
  575.         // check if . exists, if so, try parse ms
  576.         //
  577.         // FIXME: ms parsing is NOT correct here....
  578.         // 0.5 should really be 500 ms, rather than 5 here.
  579.  
  580.         // must compare >= 0 to force numeric comparison instead of lexical
  581.         if (dot >= 0) {
  582.           if (zee >= 0) { ms = timeStr.substring( dot + 1, zee); }
  583.           else if (plus >= 0) { ms = timeStr.substring( dot + 1, plus); }
  584.           else if (minus >= 0) { ms = timeStr.substring( dot + 1, minus); } 
  585.           else { ms = 0; }
  586.         }
  587.  
  588. //        updater.console.println(ms);
  589.  
  590.         if (zee >= 0) { timezone = "Z"; }
  591.         else if (plus >= 0) { timezone = timeStr.substring( plus, plus + 5); }
  592.         else if (minus >= 0 ) { timezone = timeStr.substring( minus, minus + 5); }
  593.         else { timezone = "Z"; }
  594.  
  595. //        updater.console.println("timezone = " + timezone);
  596.       }
  597.  
  598.       //updater.console.println("returning");
  599.       return new Date(Date.UTC(year, month, day, hours, mins, secs, ms));
  600.     },
  601.  
  602.     // replace as many %s in str with replacements in array in order
  603.     ReplacePrintfToken: function(str, array) {
  604.       if (array.constructor != Array || array.length == 0) return str;
  605.       if (str.constructor != String || str.length == 0) return str;
  606.  
  607.       var token = "%s";
  608.       for (var i = 0; i < array.length; i++) {
  609.         str = str.replace(token, array[i]);
  610.         }
  611.       
  612.       return str;
  613.     },
  614.  
  615.     // 
  616.     // return Date Object
  617.     // the first update time is 25 + [1-10] days from now
  618.     CreateFirstUpdateTime: function()
  619.     {
  620.         var t = new Date(); // current time in UTC
  621.         var fuss = ((Math.random() * 7) + 28) * (1000 * 60 * 60 * 24); // in ms
  622.         var ms = t.getTime();
  623.         ms += fuss;
  624.         var first = new Date(ms);
  625.         // updater.console.println("now = " + t);
  626.         // updater.console.println("next = " + next);
  627.  
  628.         return first;
  629.     },
  630.  
  631.     isTimeToUpdate: function()
  632.     {
  633.       // define nextCheckDate
  634.       // updater.console.println("isTimeToUpdate()");
  635.  
  636.         if (!this.PropertyIsDefined(updater, "nextCheckDate")) {
  637.           //updater.console.println("nextCheckDate not defined; define it now");
  638.           updater.nextCheckDate = this.CreateFirstUpdateTime();
  639.           updater.console.println("nextCheckDate = " + updater.nextCheckDate);          }
  640.  
  641.         //return true;
  642.  
  643.         var now = new Date();
  644.  
  645.         if (now.getTime() > updater.nextCheckDate.getTime()) {
  646.             updater.console.println("-->It is time to do auto update");
  647.             return true;
  648.         } else {
  649.             updater.console.println("-->It is NOT time to do auto update yet.  will check on:");
  650.             updater.console.println(updater.nextCheckDate);
  651.             return false;
  652.         }
  653.     },
  654.  
  655.     advanceNextCheckDate: function()
  656.     {
  657.         updater.console.println("advanceNextCheckDate()");
  658.         var next_ms = updater.nextCheckDate.getTime() +  30 * (1000 * 60 * 60 * 24); // in ms
  659.         var later = new Date(next_ms);
  660.         updater.nextCheckDate = later;
  661.     },
  662.  
  663.     loadState: function()
  664.     {
  665.       updater.console.println("updater loading store");
  666.       try {
  667.         updater.store.load();
  668.         }
  669.       catch (e) {
  670.         updater.console.println("Exception in loadState(): " + e);
  671.         updater.console.println("  --> skip loading store");
  672.         }
  673.       // updater.console.println("..loading nextCheckDate");
  674.       if (this.PropertyIsDefined(updater.store.perUser, "nextCheckDate")) {
  675.         updater.nextCheckDate = new Date(Date.parse(updater.store.perUser.nextCheckDate));
  676.         updater.console.println(".. nextCheckDate = " + updater.nextCheckDate);
  677.         }
  678.       
  679.       // viewed messages
  680.       //updater.console.println("..loading viewedMessages");
  681.       if (this.PropertyIsDefined(updater.store.perUser, "viewedMessages")) {
  682.         updater.viewedMessages = updater.store.perUser.viewedMessages;
  683.         //this.DumpObject(updater.viewedMessages);
  684.         }
  685.       else {
  686.         updater.viewedMessages = {};
  687.         }
  688.     },
  689.  
  690.     
  691.     saveState: function()
  692.     {
  693.       updater.console.println("updater saving store");
  694.       //updater.console.println("..saving nextCheckDate");
  695.       if (this.PropertyIsDefined(updater, "nextCheckDate")) {
  696.         updater.store.perUser.nextCheckDate = updater.nextCheckDate.toUTCString();
  697.         //updater.console.println("..saving nextCheckDate ok");
  698.         }
  699.           
  700.       //updater.console.println("..saving viewedMessages");
  701.       if (this.PropertyIsDefined(updater, "viewedMessages")) {
  702.         updater.store.perUser.viewedMessages = updater.viewedMessages;
  703.         //this.DumpObject(updater.viewedMessages);
  704.         //updater.console.println("..saving viewedMessages ok");
  705.         }
  706.  
  707.       try {
  708.         updater.store.save();
  709.         }
  710.       catch (e) {
  711.         updater.console.println("Exception in saveState(): " + e);
  712.         throw new Error("SaveStateException");
  713.         }
  714.     },
  715.  
  716.     // will pop up a dialog warning user if no net connection is found
  717.     checkNetConnection: function(skipUI) 
  718.     {
  719.       var hasNet; 
  720.       if ( typeof(updater.net["isConnected"]) != "undefined") {
  721.         hasNet = updater.net.isConnected();
  722.         }
  723.       else {
  724.         hasNet = updater.dlm.hasNetAccess();
  725.         }
  726.       
  727.       if (!hasNet && !skipUI) {
  728.         var title = updater.app.getUpdaterString("bsJSNoNetConnectTitle");
  729.         var errMsg = updater.app.getUpdaterString("bsJSNoNetConnectText");
  730.         updater.app.alert({nIcon:0, nType:0, cTitle:title, cMsg:errMsg});
  731.         return false;
  732.       }
  733.       else {
  734.         return true;
  735.       }
  736.     },
  737.  
  738.  
  739.     // dialog for missing component
  740.     showMissingCompDialog: function(cName) {
  741.       var text;
  742.       var title = updater.app.getUpdaterString("csJSMissCompTitle");
  743.       
  744.       if (!cName || cName.length == 0) {
  745.         text = updater.app.getUpdaterString("csJSMissCompText");
  746.         }
  747.       else {
  748.         text = updater.MasterScript.ReplacePrintfToken(updater.app.getUpdaterString("csJSMissCompTextName"),
  749.                                                        [cName]);
  750.         }
  751.       return updater.app.alert({nIcon:2, nType:2, cTitle:title, cMsg:text});
  752.     },
  753.  
  754.     wellKnownCompDesc: {
  755.       "Plugin/EBook" : function() {
  756.         return updater.app.getUpdaterString("IDS_SAI_EBOOK_NAME");
  757.       },
  758.       
  759.       "Plugin/MultiMedia": function() { 
  760.         return updater.app.getUpdaterString("IDS_SAI_MULTIMEDIA_NAME");
  761.       },
  762.       
  763.       "Plugin/PictureTasks": function() { 
  764.         return updater.app.getUpdaterString("IDS_SAI_MULTIMEDIA_NAME");
  765.       },
  766.  
  767.       "Annot/Screen": function() { 
  768.         return updater.app.getUpdaterString("IDS_SAI_MULTIMEDIA_NAME");
  769.       },
  770.  
  771.       "Annot/Movie": function() { 
  772.         return updater.app.getUpdaterString("IDS_SAI_MULTIMEDIA_NAME");
  773.       },
  774.  
  775.       "AsianFont/TChn": function() { 
  776.         return updater.app.getUpdaterString("IDS_SAI_ASIANFONT_CHT_NAME");
  777.       },
  778.  
  779.       "AsianFont/SChn": function() { 
  780.         return updater.app.getUpdaterString("IDS_SAI_ASIANFONT_CHS_NAME");
  781.       },
  782.  
  783.       "AsianFont/Japn": function() { 
  784.         return updater.app.getUpdaterString("IDS_SAI_ASIANFONT_JPN_NAME");
  785.       },
  786.       
  787.       "AsianFont/Kore": function() { 
  788.         return updater.app.getUpdaterString("IDS_SAI_ASIANFONT_KOR_NAME");
  789.       }
  790.       },
  791.  
  792.     // First look up in updater.wellKnownCompDesc (maybe updated by
  793.     // CodeScipt) if missing, then look up in
  794.     // updater.MasterScript.wellKnownCompDesc (the default list)
  795.     // returns a non zero length string if desc is known and found for comp
  796.     lookUpWellKnownCompDesc: function(type, name) {
  797.       var l;
  798.       var key = type + "/" + name;
  799.       if (updater.MasterScript.PropertyIsDefined(updater, "wellKnownCompDesc")) {
  800.         updater.console.println("  using updater.wellKnownCompDesc");
  801.         l = updater.wellKnownCompDesc;
  802.         }
  803.       else {
  804.         updater.console.println("  using updater.MasterScript.wellKnownCompDesc"); 
  805.         l = updater.MasterScript.wellKnownCompDesc;
  806.         }
  807.       if (! updater.MasterScript.PropertyIsDefined(l, key) ) {
  808.         updater.console.println("  cannot find prop " + key);
  809.         return null;
  810.         }
  811.       if (l[key].constructor == Function) {
  812.         try {
  813.           updater.console.println("  calling " + key + " as function");
  814.           return l[key].call();
  815.           }
  816.         catch (e) {
  817.           updater.console.println("Exception calling wellKnownCompDesc." + key);
  818.           return null;
  819.           }
  820.         }
  821.       else 
  822.         return l[key];
  823.     },
  824.  
  825.     // MasterScript Entry Point
  826.     // app.findComponent()
  827.     findComponent: function(type, name, desc, ver, params)
  828.     {
  829.       try {
  830.         return this.FindComponentAsync(type, name, desc, ver, params);
  831.         }
  832.       catch (e) {
  833.         updater.console.println("exception in findComponent: " + e);
  834.         return false;
  835.         }
  836.     },
  837.  
  838.     // MasterScript Entry Point
  839.     //   this is called by the idle proc
  840.     CheckDLMState: function()
  841.     {
  842.       try {
  843.         updater.MasterScript.asset(false, "CheckDLMState is obsoleted and should not be called.  DLM state checking is now done by AutoUpdateAsync");
  844.         return;
  845.         }
  846.       catch (e) {
  847.         updater.console.println("exception in CheckDLMState: " + e);
  848.         }
  849.     },
  850.  
  851.  
  852.     // find out which message-only notification user has not read and pop up
  853.     // modal dialogs
  854.     popNotifications: function()
  855.     {
  856.       try {
  857.         updater.console.println("  MasterScript popNotifications()");
  858.  
  859.         if ( ! this.init(true) ) return;
  860.  
  861.         updater.console.println("popNotifications()");
  862.  
  863.         // since called AFTER doUpdate(), just need to check if required
  864.         // scripts exist. also, check user pref. if so, pop new notifications
  865.         var notiEnable = updater.avpref.get("Updater", "ShowNotifDialog", 
  866.                                             updater.avpref.type["Boolean"], false);
  867.         // bail out if user doesn't want to see notifications
  868.         if (!notiEnable) { return; }
  869.         
  870.         var hasAllScripts = updater.MasterScript.getAllScriptsFromStore();
  871.  
  872.         updater.console.println("notiEnable = " + notiEnable);
  873.         updater.console.println("hasAllScripts = " + hasAllScripts);
  874.         if (notiEnable && hasAllScripts) {
  875.           updater.DataScript.entryPoint({func:"popNotifications", args:{}});
  876.           }
  877.         updater.console.println("popNotifications() Done");
  878.         }
  879.       catch (e) {
  880.         updater.console.println("exception in popNotifications: " + e);
  881.         return false;
  882.         }
  883.     },
  884.  
  885.     // URL utils
  886.     urlGetProgUI: {
  887.       cancelled: false,
  888.       initialize: function(dialog) 
  889.         {
  890.           currentDialog = dialog;
  891.           this.cancelled = false;
  892.         },
  893.       commit: function(dialog) {},
  894.       close: function()
  895.         {
  896.           if(currentDialog)
  897.             {
  898.             currentDialog.end();
  899.             return true;
  900.             } else return false;
  901.         },
  902.       "cncl": function(dialog) {
  903.         updater.console.println("  cancelled progress dialog");
  904.         this.cancelled = true;
  905.         this.close();
  906.       },
  907.       description: {
  908.         name: updater.app.getUpdaterString("msJSChkForUpdtTitle"),
  909.         elements:
  910.         [
  911.             {
  912.             type: "view",
  913.             align_children: "align_left",
  914.             elements: [
  915.                 {
  916.                 type: "static_text",
  917.                 name: updater.app.getUpdaterString("msJSChkForUpdtText"),
  918.                 alignment: "align_center",
  919.                 width: 200
  920.                 },
  921.                 {
  922.                 type: "view",
  923.                 alignment: "align_fill",
  924.                 align_children: "align_fill",
  925.                 elements:[
  926.                     {
  927.                     type: "button",
  928.                     item_id: "cncl",
  929.                     name: updater.app.getUpdaterString("msJSChkForUpdtCancel"),
  930.                     alignment: "align_center"
  931.                     }
  932.                   ]
  933.                 }
  934.               ]
  935.             }
  936.         ]
  937.       }
  938.     },
  939.  
  940.     urlMonTask: function()
  941.     {
  942.       try {
  943.         updater.console.println("enter gURLMonTask");
  944.         var mon = updater.gURLMon;
  945.         if (! mon.done) { 
  946.           updater.console.println("     gURLMonTask waits...");
  947.           mon.wait();
  948.         }
  949.         else {
  950.           updater.console.println("     gURLMonTask got all...");
  951.          if (updater.gURLMonTask) {
  952.             updater.app.clearInterval(updater.gURLMonTask);
  953.             updater.gURLMonTask = null;
  954.            }
  955.          updater.MasterScript.urlGetProgUI.close();
  956.         }
  957.         updater.console.println("exit gURLMonTask");
  958.         }
  959.       catch (e) {
  960.         if (updater.gURLMonTask) {
  961.           updater.app.clearInterval(updater.gURLMonTask);
  962.           updater.gURLMonTask = null;
  963.           }
  964.         updater.MasterScript.urlGetProgUI.close();
  965.         updater.console.println("Exception in URLMonTask" + e);
  966.       }
  967.     },
  968.  
  969.     // ifModSinceDate: js Date obj
  970.     urlGetAsyncJSUI: function(url, ifModSinceDate)
  971.     {
  972.       updater.console.println("Enter urlGetAsyncUI");
  973.       if (updater.gURLMonTask || updater.gURLMon ) {
  974.         updater.console.println("gURLMonTask or gURLMon non-null! throwing...");
  975.         throw new Error("Fatal error: urlGetAsyncUI is in progress!!");
  976.       }
  977.  
  978.       var taskStr = "updater.MasterScript.urlMonTask();";
  979.       
  980.       updater.console.println("--- Added IdleProc");
  981.       if (ifModSinceDate) {
  982.         updater.gURLMon = updater.net.urlGetAsync(url, ifModSinceDate.toUTCString());
  983.       }
  984.       else {
  985.         updater.gURLMon = updater.net.urlGetAsync(url);
  986.       }
  987.       updater.gURLMonTask = updater.app.setInterval(taskStr, 1000);
  988.       updater.gURLMon.wait();
  989.       updater.app.execDialog(this.urlGetProgUI);
  990.  
  991.       if ( this.urlGetProgUI.cancelled ) {
  992.         if (updater.gURLMonTask) {
  993.           updater.app.clearInterval(updater.gURLMonTask);
  994.           updater.gURLMonTask = null;
  995.         }
  996.         updater.gURLMon.cancel();
  997.         updater.gURLMon = null;
  998.  
  999.         updater.console.println("urlGetAyncUI cancelled!  throwing...");
  1000.         throw new Error("urlGetAyncUI cancelled");
  1001.       }
  1002.       var resp = updater.gURLMon.response;
  1003.  
  1004.       updater.gURLMonTask = null;
  1005.       updater.gURLMon = null;
  1006.  
  1007.       updater.console.println("Exit urlGetAsyncUI");
  1008.       updater.console.println(" http response status = " + resp["Status"]);
  1009.       return resp;
  1010.     },
  1011.  
  1012.     // ifModSinceDate: js Date obj
  1013.     // use blocking updater.net.urlGet
  1014.     urlGetUI: function(url, ifModSinceDate, closeUI)
  1015.     {
  1016.       updater.console.println("Enter urlGetUI");
  1017.  
  1018.       // for backward compatibility
  1019. //       if ( !this.PropertyIsDefined(updater.app, "showProgressDialog") ) {
  1020. //         var resp;
  1021. //         if (ifModSinceDate) {
  1022. //           updater.console.println(" -- pt 1 ");          
  1023. //           resp = updater.net.urlGet(url, ifModSinceDate.toUTCString());
  1024. //           this.DumpObject(ifModSinceDate);
  1025. //           updater.console.println(" -- pt 2 "); 
  1026. //         }
  1027. //         else {
  1028. //           resp = updater.net.urlGet(url);
  1029. //         }
  1030. //         return resp;
  1031. //       }
  1032.  
  1033.       // new
  1034.       if (!updater.isAutoUpdate) {
  1035.         updater.app.showProgressDialog();
  1036.       }
  1037.       updater.app.processDialogEvent();
  1038.  
  1039.       var resp;
  1040.       if (ifModSinceDate) {
  1041.         updater.console.println(" start urlGet() using if-mod-since");
  1042.         resp = updater.net.urlGet(url, ifModSinceDate.toUTCString());
  1043.         updater.console.println(" done urlGet()");
  1044.         }
  1045.       else {
  1046.         updater.console.println(" start urlGet()");
  1047.         resp = updater.net.urlGet(url);
  1048.         updater.console.println(" done urlGet()"); 
  1049.         }
  1050.  
  1051.       updater.app.processDialogEvent();
  1052.       if (closeUI) {
  1053.         updater.app.hideProgressDialog();
  1054.         }
  1055.  
  1056.       // this.DumpObject(resp);
  1057.  
  1058.       if ( updater.app.isProgressDialogCancelled() ) {
  1059.         throw new Error("ProgressDialog Cancelled");
  1060.         }
  1061.       
  1062.       updater.console.println("Exit urlGetUI");
  1063.       return resp;
  1064.     },
  1065.  
  1066.  
  1067.     // ifModSinceDate: js Date obj
  1068.     // use Async updater.net.urlGetAsync
  1069.     urlGetAsyncUI: function(url, ifModSinceDate, closeUI)
  1070.     {
  1071.       updater.console.println("Enter urlGetUIAsync");
  1072.  
  1073.       // new
  1074.       // updater.isAutoUpdate is a gloabl
  1075.       if (! updater.isAutoUpdate) {
  1076.         updater.app.showProgressDialog();
  1077.       }
  1078.  
  1079.       var mon;
  1080.       if (ifModSinceDate) {
  1081.         updater.console.println(" calls updater.net.urlGetAsync() using if-mod-since");
  1082.         mon = updater.net.urlGetAsync(url, ifModSinceDate.toUTCString());
  1083.         }
  1084.       else {
  1085.         updater.console.println(" calls updater.net.urlGetAsync()");
  1086.         mon = updater.net.urlGetAsync(url);
  1087.         }
  1088.  
  1089.       // loop for waiting for async get
  1090.       updater.console.println(" start looping url mon");
  1091.       while (! mon.done) {
  1092.         //updater.console.println("  ...waiting mon");
  1093.         updater.app.processDialogEvent();
  1094.         mon.wait();
  1095.         updater.app.processDialogEvent();
  1096.         if ( updater.app.isProgressDialogCancelled() ) {
  1097.           updater.console.println("  ...cancelling mon");
  1098.           mon.cancel(); 
  1099.           // updater.app.processDialogEvent();
  1100.           updater.app.hideProgressDialog();
  1101.           throw "URLGetCancelled";
  1102.           }
  1103.         }
  1104.       if (closeUI) {
  1105.         updater.app.hideProgressDialog();
  1106.         }
  1107.  
  1108.       var resp = mon.response;
  1109.  
  1110.       updater.console.println("Exit urlGetUIAsync");
  1111.       return resp;
  1112.     },
  1113.  
  1114.     //
  1115.     // FixUp the cacheScriptName so that it is product and language
  1116.     // dependent
  1117.     // eg: cachedMasterScript -> cachedMasterScript_Exchange-Pro_JPN
  1118.     //     cachedDataScript -> cachedDataScript_Reader_FRA
  1119.     //
  1120.     FixUpCacheScriptName: function(str) {
  1121.       var ret = str + "_" + updater.app.viewerType + "_" + updater.app.language;
  1122.       return ret;
  1123.     },
  1124.     // 
  1125.     // updater.tmp
  1126.     // updater.MasterScript
  1127.     // updater.DataScript
  1128.     // updater.CodeScript
  1129.     // updater.UIScript
  1130.     //
  1131.  
  1132.     //
  1133.     // updater.store.perUser:
  1134.     //   cachedMasterScript = { cachedDate: Date, scriptObj: script };
  1135.     //   cachedDataScript
  1136.     //   cachedCodeScript
  1137.     //   cachedUIScript
  1138.     //   nextCheckDate
  1139.     // 
  1140.     // CachedScript obj is like { cachedDate: Date, scriptObj: script };
  1141.     //
  1142.     
  1143.     // The input scriptCacheName are cachedMasterScript, cachedDataScript,
  1144.     // cachedCodeScript, cachedUIScript, etc.
  1145.     // 
  1146.     // scriptCacheName are postpended with prodConfig and Lang:
  1147.     // eg: cachedMasterScript -> cachedMasterScript_Exchange-Pro_JPN
  1148.     //     cachedDataScript -> cachedDataScript_Reader_FRA
  1149.     //
  1150.     // the postpended names are the actually names used in udstore.js
  1151.     //
  1152.     GetCachedScriptObj: function(serializationRoot, // updater.store.perUser
  1153.                                  scriptCacheName) // cachedDataScript, name for a CachedScript obj
  1154.     {
  1155.       updater.console.println("  GetCachedScriptObj()");
  1156.       var cachedScriptObj = null;
  1157.       
  1158.       // Should validate input params here!
  1159.       if (! scriptCacheName || scriptCacheName.length <=0 ) { throw "InvalidCachedName"; };
  1160.       
  1161.       scriptCacheName = this.FixUpCacheScriptName(scriptCacheName);
  1162.       updater.console.println("  scriptCacheName = " + scriptCacheName);
  1163.       
  1164.       // var serializationRoot = updater.store.perUser;
  1165.       
  1166.       // Do we have a cached data script object? If so, grab the date
  1167.       // associated with it.  This represents the moddate (in server-time) of
  1168.       // the data.
  1169.  
  1170.       try {
  1171.         // try finding cachedScriptModDate from presisted script
  1172.         if ( this.PropertyIsDefined(serializationRoot, scriptCacheName) ) {
  1173.  
  1174.           // Looks like we have a cached data script obj.  Just to be safe,
  1175.           // we'll ensure that it has the required keys
  1176.           // var cachedScriptObj = serializationRoot.cachedDataScript;
  1177.           cachedScriptObj = serializationRoot[scriptCacheName];
  1178.  
  1179.           // the cachedScriptObj must have prop scriptObj and cachedData
  1180.           if ( !this.PropertyIsDefined( cachedScriptObj, "scriptObj" ) || !this.PropertyIsDefined( cachedScriptObj, "cachedDate" ) ) {
  1181.             updater.console.println("   corrupted scriptobj");
  1182.             // missing a critical prop! nuke the cache info
  1183.             // delete serializationRoot.cachedDataScript;
  1184.             delete serializationRoot[scriptCacheName];
  1185.             }
  1186.             // else {
  1187.             // setup to use the moddate of the data JS in an if-modified-since query
  1188.             // cachedScriptModDate = new Date(Date.parse(cachedScriptObj.cachedDate));
  1189.             //updater.console.println("  cachedScriptObj.cachedDate = " + cachedScriptModDate);
  1190.             // }
  1191.  
  1192.           // if older version of DataScript < 0.02
  1193.           // updater.console.println("  cachedScript version = " + cachedScriptObj.scriptObj.version);
  1194.           
  1195.           //if (cachedScriptObj.scriptObj.version < "0.02") {
  1196.           //updater.console.println(" has older DataScript.  force loading new one");
  1197.           //cachedScriptModDate = null;
  1198.           //}
  1199.           }
  1200.         }
  1201.       catch (e) {
  1202.         updater.console.println(" exception in finding out cachedScriptModDate ");
  1203.         updater.console.println(" setting cachedScriptModDate to null");
  1204.       }
  1205.       return cachedScriptObj;
  1206.     },
  1207.  
  1208.     GetCachedScriptModDate: function(cachedScriptObj)
  1209.     {
  1210.       updater.console.println("  GetCachedScriptModDate()");
  1211.       var cachedScriptModDate = null; 
  1212.       if ( cachedScriptObj && this.PropertyIsDefined( cachedScriptObj, "cachedDate" ) ) {
  1213.         cachedScriptModDate  = new Date(Date.parse(cachedScriptObj.cachedDate));
  1214.         }
  1215.       return cachedScriptModDate;
  1216.     },
  1217.  
  1218.     // returns a resp obj
  1219.     DownloadScript: function(scriptURL, cachedScriptModDate)
  1220.     {
  1221.       updater.console.println("  DownloadScript()");
  1222.       var resp;
  1223.       try {
  1224.         if (cachedScriptModDate) {
  1225.           updater.console.println("  Using if-mod-since");
  1226.           if (updater.useSyncRead) {
  1227.             resp = this.urlGetUI(scriptURL, cachedScriptModDate);
  1228.             }
  1229.           else {
  1230.             resp = this.urlGetAsyncUI(scriptURL, cachedScriptModDate);
  1231.             }
  1232.           }
  1233.         else {
  1234.           updater.console.println("  NOT Using if-mod-since");
  1235.           if (updater.useSyncRead) {
  1236.             resp = this.urlGetUI(scriptURL);
  1237.             }
  1238.           else {
  1239.             resp = this.urlGetAsyncUI(scriptURL);
  1240.             }
  1241.           }
  1242.         }
  1243.       catch (e) {
  1244.         if (e == "URLGetCancelled") {
  1245.           throw "DownloadCancelled";
  1246.         }
  1247.         updater.console.println("Exception raised from updater.net.urlGet() or urlGetAsync() - " + e);
  1248.         updater.app.hideProgressDialog();
  1249.         throw "URLGetException";
  1250.         }
  1251.       return resp;
  1252.     },
  1253.  
  1254.     // return a scriptObj 
  1255.     GetAndCacheScriptObjFromResp: function(cachedScriptObj, resp, 
  1256.                                            serializationRoot, scriptCacheName)
  1257.     {
  1258.       updater.console.println("  GetAndCacheScriptObjFromResp()");
  1259.       scriptCacheName = this.FixUpCacheScriptName(scriptCacheName);
  1260.       updater.console.println("  scriptCacheName = " + scriptCacheName);
  1261.  
  1262.       // If we succesfully downloaded the data script, or if we got a not-modified result, we need to grab the
  1263.       // date returned by the server, which we'll use as our new last-check date.  This avoids clock skew
  1264.       // between the local machine and the server.
  1265.       var serverDate = null;
  1266.  
  1267.       updater.console.println("  checking response status");
  1268.       if (!resp || ! this.PropertyIsDefined(resp, "Status")) {
  1269.         updater.app.hideProgressDialog();
  1270.         throw "NoReponseStatus";
  1271.       }
  1272.  
  1273.       updater.console.println("  http response status = " + resp["Status"]);
  1274.  
  1275.       // if-modified-since case
  1276.       if (resp["Status"] == 304) {
  1277.         updater.console.println("  if-mod-since used since server response status = " + resp["Status"]);
  1278.         // used the cached datascript
  1279.         // updater.DataScript = cachedScriptObj.scriptObj;
  1280.         return cachedScriptObj.scriptObj;
  1281.         }
  1282.  
  1283.       // all other server error
  1284.       if (resp["Status"] != 200) {
  1285.         updater.app.hideProgressDialog();          
  1286.         throw "ServerError";
  1287.         }
  1288.  
  1289.       // Status = 200
  1290.       updater.console.println("  got newer content from server");
  1291.       // updater.console.println("resp.Content = " + resp.Content.substr(0, 30));
  1292.       // Get rid of the old cached data since it is out of date
  1293.       // delete serializationRoot.cachedDataScript;
  1294.       delete serializationRoot[scriptCacheName];
  1295.       
  1296.       if ( this.PropertyIsDefined( resp.Headers, "Date" ) ) {
  1297.         serverDate = this.GenASN1ToDate( resp.Headers["Date"] );
  1298.         updater.console.println("  Got Server Date ");
  1299.         }
  1300.       else {
  1301.         // illegal HTTP response without a Date header!
  1302.         updater.console.println("  illegal HTTP response without a Date header!  throw!");
  1303.         updater.app.hideProgressDialog();
  1304.         throw "NoDateHeader";
  1305.         }
  1306.  
  1307.       // Get the new moddate for the downloaded data out of the HTTP response headers.  Per HTTP 1.1 spec
  1308.       // section 14.25, we'll first try to get the Last-Modified header.  Failing this, we'll use the value
  1309.       // of the date header (which we retrieved above and stored in serverDate)
  1310.       var newModDate;
  1311.       if ( this.PropertyIsDefined( resp.Headers, "Last-Modified" ) ) {
  1312.         updater.console.println("  using Last-Modified to cache");
  1313.         newModDate = this.GenASN1ToDate( resp.Headers["Last-Modified"] );
  1314.         }
  1315.       else {
  1316.         updater.console.println("  using serverDate to cache");
  1317.         newModDate = serverDate;
  1318.         }
  1319.       updater.console.println("  newModDate = " + newModDate);
  1320.       
  1321.       // eval the returned data.  If this pukes, it'll throw.  We'll put in a check for null as well
  1322.       // just to be paranoid
  1323.       updater.console.println("  Eval resp.Content ");
  1324.       var newScriptObj = eval( resp.Content );
  1325.       if ( newScriptObj == null ) {
  1326.         updater.console.println("  Something wrong while eval resp.Content.  throws!");
  1327.         updater.app.hideProgressDialog();
  1328.         throw "BadData";
  1329.         }
  1330.         
  1331.       // Put the new cached data where it belongs
  1332.       updater.console.println("  Caching Content");
  1333.       // serializationRoot.cachedDataScript = { cachedDate : newModDate, scriptObj : newScriptObj };
  1334.       serializationRoot[scriptCacheName] = { cachedDate : newModDate, scriptObj : newScriptObj };
  1335.       
  1336.       // updater.DataScript = newScriptObj;
  1337.       return newScriptObj;
  1338.     },
  1339.  
  1340.     // return scriptObj
  1341.     downloadAndCacheScript: function(scriptURL,
  1342.                                      serializationRoot, // updater.store.perUser
  1343.                                      scriptCacheName // cachedDataScript, name for a CachedScript obj
  1344.                                      ) {
  1345.  
  1346.       if (! scriptURL || scriptURL.length <=0 ) { throw "InvalidScriptURL"; };
  1347.       updater.console.println("===== downloadAndCacheScript =====");
  1348.       updater.console.println("   url = " + scriptURL);
  1349.  
  1350.       var cachedScriptObj = null;
  1351.       cachedScriptObj = this.GetCachedScriptObj(serializationRoot, scriptCacheName);
  1352.  
  1353.       var cachedScriptModDate = null;
  1354.       cachedScriptModDate = this.GetCachedScriptModDate(cachedScriptObj);
  1355.  
  1356.       var resp = null;
  1357.  
  1358.       resp = this.DownloadScript(scriptURL, cachedScriptModDate);
  1359.       
  1360.       var scriptObj = null;
  1361.       scriptObj = this.GetAndCacheScriptObjFromResp(cachedScriptObj, resp, 
  1362.                                                     serializationRoot, scriptCacheName);
  1363.  
  1364.       return scriptObj;
  1365.     },
  1366.  
  1367.  
  1368.     // return a script or null
  1369.     getScriptFromStore: function(serializationRoot, 
  1370.                                  scriptCacheName) {
  1371.       if (updater.MasterScript.PropertyIsDefined(serializationRoot, scriptCacheName)) {
  1372.         updater.console.println("getScriptFromStore got " + scriptCacheName);
  1373.         return serializationRoot[scriptCacheName].scriptObj;
  1374.         
  1375.         }
  1376.       else {
  1377.         updater.console.println("getScriptFromStore returns null ");
  1378.         return null;
  1379.         }
  1380.     },
  1381.     // bring all scripts to runtime from store
  1382.     // only called by popNotifications().
  1383.     // will NOT go to net and fetch latest script
  1384.     // return true if all scripts exist
  1385.     getAllScriptsFromStore: function() {
  1386.       if (!updater.MasterScript.PropertyIsDefined(updater, "DataScript")) {
  1387.         var ret = updater.MasterScript.getScriptFromStore(updater.store.perUser, "cachedDataScript");
  1388.         if (ret != null) { updater.DataScript = ret; }
  1389.       }
  1390.  
  1391.       if (!updater.MasterScript.PropertyIsDefined(updater, "UIScript")) {
  1392.         var ret = updater.MasterScript.getScriptFromStore(updater.store.perUser, "cachedUIScript");
  1393.         if (ret != null) { updater.UIScript = ret; }
  1394.       }
  1395.  
  1396.       if (!updater.MasterScript.PropertyIsDefined(updater, "CodeScript")) {
  1397.         var ret = updater.MasterScript.getScriptFromStore(updater.store.perUser, "cachedCodeScript");
  1398.         if (ret != null) { updater.CodeScript = ret; }
  1399.       }
  1400.  
  1401.       return (updater.MasterScript.PropertyIsDefined(updater, "DataScript")
  1402.               && updater.MasterScript.PropertyIsDefined(updater, "UIScript")
  1403.               && updater.MasterScript.PropertyIsDefined(updater, "CodeScript"));
  1404.     },
  1405.  
  1406.     // Dev Tests
  1407.     
  1408.     getTestMasterURL: function()
  1409.     {
  1410.         var testmaster = "TestMaster.js";
  1411.         var ret = updater.scriptRootURL + testmaster;
  1412.         return ret;
  1413.     },
  1414.  
  1415.  
  1416.     testExec: function()
  1417.     {
  1418.       // this.findComponent("annotation", "bumper sticker");
  1419.       this.popNotifications();
  1420.       
  1421. //       var d1 = "20021107061101Z";
  1422. //       var d2 = "20010315182201.27Z";
  1423. //       var d3 = "20020910213422.56-0200";
  1424.  
  1425. //       var res = updater.MasterScript.GenASN1ToDate(d1);
  1426. //       updater.console.println(" d1 = " + res.toUTCString());
  1427.  
  1428. //       var res = updater.MasterScript.GenASN1ToDate(d2);
  1429. //       updater.console.println(" d1 = " + res.toUTCString());
  1430.  
  1431. //       var res = updater.MasterScript.GenASN1ToDate(d3);
  1432. //       updater.console.println(" d1 = " + res.toUTCString());
  1433.  
  1434. //       return;
  1435.  
  1436.       updater.console.println("Start Updater Test");
  1437.  
  1438.         var testMasterURL = this.getTestMasterURL();
  1439.         var testScript;
  1440.         try {
  1441.           var resp;
  1442.           // resp = this.urlGetAsyncUI(testMasterURL);
  1443.           resp = updater.MasterScript.urlGetUI(testMasterURL, null, true);
  1444.           updater.console.println("  Got TestMaster");
  1445.           updater.TestMaster = eval(resp.Content);
  1446.           updater.console.println("  Eval TestMaster done");
  1447.  
  1448.           if (this.PropertyIsDefined(updater, "TestMaster")) {
  1449.             updater.TestMaster.exec();
  1450.             }
  1451.           else {
  1452.             updater.console.println("  Cannot load TestMaster");
  1453.             }
  1454.         }
  1455.         catch (e) {
  1456.           updater.console.println("exception while fetching TestMaster:  " + e);
  1457.         }
  1458.     },
  1459.     
  1460.     
  1461.  
  1462.  
  1463.     // Pref Panel
  1464.     GetUpdaterPrefPanel: function() {
  1465.       var updatePanelName = updater.app.getUpdaterString("IDS_PREFS_PANEL_UPDATE");
  1466.       var monthlyText = updater.app.getUpdaterString("IDS_PREFS_PANEL_UPDATEMONTHLY");
  1467.       var manuallyText = updater.app.getUpdaterString("IDS_PREFS_PANEL_UPDATEMANUALLY");
  1468.       var gStaticTextHeight = 13;
  1469.       var gPrefsPanelWidth = 550;
  1470.       var gPrefsPanelHeight = 390;
  1471.  
  1472.       var updaterPrefPanel = {
  1473.       version: "0.01",
  1474.  
  1475.       // get all localized strings from getUpdaterString
  1476. //       l10n_init: function(dialog) {
  1477. //         updater.console.println("  l10n_init()");
  1478.  
  1479. //         // load up the l10n strings
  1480. //         //dialog.load( { "text" : this.updateDescText } );
  1481. //         // viewer and reader case
  1482.  
  1483. //         dialog.load({ "nctx" : this.nextCheckText });
  1484. //         dialog.load({ "cfut" : this.checkForUpdatesText });
  1485. //         dialog.load({ "Noti" : this.updateNotificationBtn });
  1486. //         dialog.load({ "conf" : this.showConfirmDlgText });
  1487. //         dialog.load({ "ShNo" : this.displayStartupNotifDlgText });
  1488. //       },
  1489.  
  1490.       // constants
  1491.       monthly: 1,
  1492.       manually: 0,
  1493.       
  1494.       nextCheckText: updater.app.getUpdaterString("IDS_PREFS_PANEL_NEXTCHECK"),
  1495.       manualNextCheck: updater.app.getUpdaterString("IDS_PREFS_PANEL_MANUALNEXTCHECK"),
  1496.  
  1497.       updateDescText: updater.app.getUpdaterString("IDS_PREFS_PANEL_UPDATEDESCTEXT"),
  1498.       updateDescTextReader: updater.app.getUpdaterString("IDS_PREFS_PANEL_UPDATEDESCTEXT_READER"),
  1499.       updateAcrobatNowText: updater.app.getUpdaterString("IDS_UPDATE_ACROBAT_NOW"),
  1500.       updateReaderNowText: updater.app.getUpdaterString("IDS_UPDATE_READER_NOW"),
  1501.  
  1502.       // dsiu: TODO: need to unwind this to CodeScript
  1503.       initialize: function(dialog) {
  1504.         updater.console.println("updaterPrefDialog initialize");
  1505.  
  1506.         // this.l10n_init(dialog);
  1507.  
  1508.         var freq = updater.app.getUpdateFrequency();
  1509.         updater.console.println("  freq = " + freq);
  1510.  
  1511.         var choices = {};
  1512.         if (freq == this.monthly) {
  1513.           updater.console.println("    using monthly");
  1514.           choices[monthlyText] = 1;
  1515.           choices[manuallyText] = 0;
  1516.           }
  1517.         else {
  1518.           updater.console.println("    using manually");
  1519.           choices[monthlyText] = 0;
  1520.           choices[manuallyText] = 1;
  1521.           }
  1522.         //dialog.load( { "Freq" : { "Every Month" : (freq == this.monthly) , 
  1523.         //"Manually" : (freq == this.manually) } } );
  1524.         dialog.load( {"Freq" : choices} );
  1525.  
  1526.         // widths 
  1527.         var date;
  1528.         if (freq==this.manually)
  1529.           date = this.manualNextCheck;
  1530.         else
  1531.           {
  1532.           if (!updater.MasterScript.PropertyIsDefined(updater, "nextCheckDate"))
  1533.             {
  1534.             updater.console.println("nextCheckDate not defined; define it now");
  1535.             updater.nextCheckDate = updater.MasterScript.CreateFirstUpdateTime();
  1536.             updater.console.println("nextCheckDate = " + updater.nextCheckDate);
  1537.             }
  1538.         
  1539.           date = "" + updater.nextCheckDate;
  1540.           }
  1541.         dialog.load( { "ckAc" : (date) } );
  1542.  
  1543.         var type = updater.app.viewerType;
  1544.         if ( type == "Reader" ) {
  1545.           dialog.load( { "text" : this.updateDescTextReader } );
  1546.           dialog.load( { "UpAc" : this.updateReaderNowText } );
  1547.           }
  1548.         else {
  1549.           dialog.load( { "text" : this.updateDescText } );
  1550.           dialog.load( { "UpAc" : this.updateAcrobatNowText } );
  1551.           }
  1552.  
  1553.         dialog.load( { "conf" : updater.app.getShowUpdateDialog() } );
  1554.         dialog.load( { "ShNo" : updater.app.getShowStartupNotifDialog() } );
  1555.  
  1556.         // FIXME: 
  1557.         // enable Notification button only when there are messages
  1558.         // downloaded AND not restart pending!
  1559.         var hasAllScripts = updater.MasterScript.getAllScriptsFromStore();
  1560.         var hasMsg;
  1561.         var hasMsgFunc = function(arg) {
  1562.           updater.console.println("arg.returnVal = " + arg.returnVal);
  1563.           hasMsg = (arg.returnVal > 0);
  1564.           updater.console.println("inner hasMsg = " + hasMsg);
  1565.         };
  1566.  
  1567.         if (hasAllScripts) {
  1568.           updater.DataScript.entryPoint({func: "GetNumMessages", 
  1569.                                          args:{}, callBack: hasMsgFunc,
  1570.                                          callBackArgArgs: null});
  1571.           };
  1572.  
  1573.         updater.console.println("outter hasMsg = " + hasMsg);
  1574.         var notiEnable = hasAllScripts && 
  1575.                          (! updater.MasterScript.checkPendingRestart(true))
  1576.                          && hasMsg;
  1577.  
  1578.         dialog.enable( { "Noti" : notiEnable } );
  1579.         dialog.createNotifier( { "UpAc" : 0, "Noti" : 0 } );
  1580.       },
  1581.  
  1582.       // dsiu: TODO: need to unwind this to CodeScript
  1583.       commit: function(dialog) {
  1584.         updater.console.println("updaterPrefDialog commit");
  1585.  
  1586.         // var val = dialog.store("Freq")["Freq"];
  1587.         var val = dialog.store("Freq")["Freq"];
  1588.         var isMan = val[manuallyText];
  1589.         var isMonth = val[monthlyText];
  1590.  
  1591.         updater.console.println(" isMan = " + isMan);
  1592.         updater.console.println(" isMon  = " + isMonth); 
  1593.  
  1594.         updater.app.setUpdateFrequency(isMan ? this.manually : this.monthly);
  1595.         updater.app.setShowUpdateDialog(dialog.store("conf" )["conf"]);
  1596.         updater.app.setShowStartupNotifDialog(dialog.store("ShNo" )["ShNo"]);
  1597.       },
  1598.  
  1599.       // dsiu: TODO: need to unwind this to CodeScript
  1600.       // manual update
  1601.       "UpAc": function(dialog) {
  1602.         updater.console.println("UpAc clicked");
  1603.         updater.MasterScript.entryPoint(true);
  1604.       },
  1605.  
  1606.       // dsiu: TODO: need to unwind this to CodeScript
  1607.       "Noti": function(dialog) {
  1608.         updater.console.println("Noti clicked");
  1609.         updater.DataScript.entryPoint({func:"ShowNotifDialog", args:{}});
  1610.       },
  1611.  
  1612.       description:
  1613.       {
  1614.       name: "Update Prefs Panel",
  1615.       margin_height: "0",
  1616.       margin_width: "0",
  1617.       elements: [
  1618.           {
  1619.           type: "cluster",
  1620.           name: (updatePanelName),
  1621.           dwidth: (gPrefsPanelWidth),
  1622.           dheight: (gPrefsPanelHeight),
  1623.           align_children: "align_left",
  1624.           elements: [
  1625.               {  
  1626.               type: "static_text",
  1627.               item_id: "text",
  1628.               alignment: "align_fill",
  1629.               height: (gStaticTextHeight*5)
  1630.               },
  1631.  
  1632.               {  
  1633.               type: "view",
  1634.               align_children: "align_row",
  1635.               alignment: "align_fill",
  1636.               elements: [
  1637.                   { 
  1638.                   type: "static_text",
  1639.                   item_id: "nctx",
  1640.                   name: (nextCheckText)
  1641.                   },
  1642.                                 
  1643.                   {
  1644.                   type: "static_text",
  1645.                   item_id: "ckAc",
  1646.                   alignment: "align_fill"
  1647.                   }
  1648.                 ]
  1649.               },
  1650.  
  1651.               {
  1652.               type: "gap",
  1653.               height: (gStaticTextHeight)
  1654.               },
  1655.  
  1656.               {
  1657.               type: "view",
  1658.               align_children: "align_right",
  1659.               alignment: "align_center",
  1660.               elements: [
  1661.                   {
  1662.                   type: "view",
  1663.                   align_children: "align_row",
  1664.                   elements: [
  1665.                       {
  1666.                        type: "static_text",
  1667.                        item_id: "cfut",
  1668.                        alignment: "align_right",
  1669.                        name: (checkForUpdatesText)
  1670.                        },
  1671.                     
  1672.                       {
  1673.                       type: "popup",
  1674.                       item_id: "Freq",
  1675.                       width: (gUpdateNowWidth)
  1676.                       }
  1677.                     ]
  1678.                   },
  1679.  
  1680. //                    {
  1681. //                    type: "button",
  1682. //                    item_id: "UpAc",
  1683. //                    width: (gUpdateNowWidth),
  1684. //                    name: ""
  1685. //                    },
  1686.  
  1687.                   {
  1688.                   type: "button",
  1689.                   item_id: "Noti",
  1690.                   width: (gUpdateNowWidth),
  1691.                   name: (updateNotificationBtn)
  1692.                   }
  1693.                 ]
  1694.               },
  1695.                         
  1696.               {
  1697.               type: "gap",
  1698.               height: (gStaticTextHeight)
  1699.               },
  1700.             
  1701.               {
  1702.               type: "check_box",
  1703.               item_id: "conf",
  1704.               name: (showConfirmDlgText)
  1705.               },
  1706.             
  1707.               {
  1708.               type: "check_box",
  1709.               item_id: "ShNo",
  1710.               name: (displayStartupNotifDlgText)
  1711.               }
  1712.             ]
  1713.           }
  1714.         ]
  1715.       }
  1716.         };
  1717.       return updaterPrefPanel;
  1718.     }, // GetUpdaterPrefPanel
  1719.  
  1720.     // MasterScript Entry Point
  1721.     // called from idle proc
  1722.     InstallPrefPanel: function() 
  1723.     {
  1724.       try {
  1725.         updater.console.println("  MasterScript InstallPrefPanel()");
  1726.         if ( ! this.init(true) ) return;
  1727.  
  1728.         updater.console.println("InstallPrefPanel");
  1729.       
  1730.         if (!updater.prefPanelInstalled) {
  1731.           // var prefd = this.updaterPrefPanel;
  1732.           // var prefd = updater.MasterScript.updaterPrefPanel;
  1733.           // updater.app.createJSPrefsPanel(prefd, "Updates", "Updates");
  1734.           // try using a global off updater 
  1735.           updater.prefPanel = updater.MasterScript.GetUpdaterPrefPanel();
  1736.           updater.app.createJSPrefsPanel(updater.prefPanel, 
  1737.                                          updater.app.getUpdaterString("IDS_PREFS_PANEL_UPDATE"),
  1738.                                          "Updates");
  1739.           updater.prefPanelInstalled = true;
  1740.           updater.console.println("UpdaterPrefPanel installed");
  1741.           }
  1742.         else {
  1743.           updater.console.println("UpdaterPrefPanel already installed");
  1744.           }
  1745.         updater.console.println("InstallPrefPanel Done");
  1746.         return;
  1747.         }
  1748.       catch (e) {
  1749.         updater.console.println("exception in InstallPrefPanel: " + e);
  1750.         }
  1751.     },
  1752.  
  1753.  
  1754.     //
  1755.     // General way of creating a state machine 
  1756.     //
  1757.     SStartStateMachine : function(idleProc, idleArgs, 
  1758.                                   resumeProc, resumeArgs, 
  1759.                                   name, states)
  1760.     {
  1761.       if (this.PropertyIsDefined(updater, "gStateMachineLock") &&
  1762.           updater.gStateMachineLock == true) {
  1763.         updater.console.println("SStartStateMachine locked by " + 
  1764.                                 updater.gStateMachine.name);
  1765.         throw "StateMachineInUse";
  1766.         }
  1767.       
  1768.       updater.gStateMachineLock = true;
  1769.  
  1770.       // TODO: add singleton
  1771.       updater.gStateMachine = new Object();
  1772.       var sm = updater.gStateMachine;
  1773.  
  1774.       sm.name = name;
  1775.       sm.enumStates = states;
  1776.       sm.state = states.StInit;
  1777.       sm.idleProc = idleProc;
  1778.       sm.idleArgs = idleArgs;
  1779.       sm.resumeProc = resumeProc;
  1780.       sm.resumeArgs = resumeArgs;
  1781.       sm.done = false;
  1782.       sm.error = false;
  1783.       sm.exception = null;
  1784.       // TODO: the interval in ms MUST BE greater than the ADM idle proc
  1785.       // otherwise cancel event won't be received!
  1786.       sm.handle = updater.app.setInterval(idleProc, 60);
  1787.     },
  1788.  
  1789.  
  1790.     // BgDl = Background downloading
  1791.     SBgDlStates : 
  1792.     {
  1793.       StInit: 0,
  1794.       StReadStart: 1,
  1795.       StReadWait: 2,
  1796.       StReadDone: 3,
  1797.       StShowUI: 4,
  1798.       StProcessUI: 5,
  1799.       StException: 800,
  1800.       StFinished: 999
  1801.     },
  1802.  
  1803.     //
  1804.     // This is the state machine for doing download MULTIPLE script, posting
  1805.     // progress dialog, cache script, etc.  this is a replacement for
  1806.     // loadDataScript() / downloadAndCacheScript()
  1807.     //
  1808.     SBgDlProcessState : function()
  1809.     {
  1810.       var sm = updater.gStateMachine;
  1811.  
  1812.       try {
  1813.         var state = sm.state;
  1814.         var st_enum = sm.enumStates;
  1815.         
  1816.         //updater.console.println("= SBgDlProcessState =");
  1817.         //updater.MasterScript.DumpObject(sm.idleArgs, "idleArgs", true);
  1818.  
  1819.         // unpackage the args
  1820.         var loadScriptArgs = sm.idleArgs.loadScriptArgs;
  1821.         updater.MasterScript.assert(loadScriptArgs.constructor == Array, "loadScriptArgs not an Array!");
  1822.  
  1823.         // init idx
  1824.         if (! updater.MasterScript.PropertyIsDefined(sm, "scriptArgIdx") ) {
  1825.           sm.scriptArgIdx = 0;
  1826.           }
  1827.  
  1828.         // updater.console.println("scriptArgIdx = " + sm.scriptArgIdx);
  1829.         // updater.MasterScript.DumpArray(loadScriptArgs);
  1830.  
  1831.         var lsArgs = loadScriptArgs[sm.scriptArgIdx];
  1832.         
  1833.         // cannot check assert here since lsArgs MAYBE null for the last
  1834.         // element before proceeding to the StFinished state
  1835.         //updater.MasterScript.assert(lsArgs, "lsArgs is NULL");
  1836.         // updater.MasterScript.DumpObject(lsArgs, "lsArgs", true);
  1837.  
  1838.         var scriptURL = lsArgs? lsArgs["scriptURL"] : null;
  1839.         var serializationRoot = lsArgs ? lsArgs["serializationRoot"] : null;
  1840.         var scriptCacheName = lsArgs ? lsArgs["scriptCacheName"] : null;
  1841.         var callPoint = lsArgs ? lsArgs["callPoint"] : null;
  1842.         var dontMount = lsArgs ? lsArgs["dontMount"] : null;
  1843.  
  1844.         var suppressUI = sm.idleArgs["suppressUI"];
  1845.         var closeUI = sm.idleArgs["closeUI"];
  1846.  
  1847.         switch (state) {
  1848.           case st_enum.StInit : 
  1849.             try {
  1850.               updater.console.println("=== StInit ===");
  1851.               if (! scriptURL || scriptURL.length <=0 ) { 
  1852.                 sm.exception =  "InvalidScriptURL"; 
  1853.                 sm.state = sm.StException;
  1854.                 break;
  1855.                 }
  1856.               updater.console.println("  url = " + scriptURL);
  1857.               // setup private var in sm
  1858.               sm.cachedScriptObj = null;
  1859.               sm.cachedScriptObj = updater.MasterScript.GetCachedScriptObj(serializationRoot, scriptCacheName);
  1860.               
  1861.               sm.cachedScriptModDate = null;
  1862.               sm.cachedScriptModDate = updater.MasterScript.GetCachedScriptModDate(sm.cachedScriptObj);
  1863.               
  1864.               sm.state = sm.enumStates.StShowUI;
  1865.               }
  1866.             catch (e) {
  1867.               updater.console.println("Exception in StInit: " + e);
  1868.               sm.exception = e;
  1869.               sm.state = sm.StException;
  1870.               }
  1871.             break;
  1872.  
  1873.         case st_enum.StShowUI:
  1874.           try {
  1875.             updater.console.println("=== StShowUI ===");
  1876.             if (!suppressUI) {
  1877.               updater.app.showProgressDialog();
  1878.               }
  1879.             sm.uiCancelled = false;
  1880.             sm.state = sm.enumStates.StReadStart;
  1881.             }
  1882.           catch (e) {
  1883.               updater.console.println("Exception in StShowUI: " + e);
  1884.               sm.exception = e;
  1885.               sm.state = sm.StException;
  1886.             }
  1887.           break;
  1888.           
  1889.         case st_enum.StReadStart :
  1890.           try {
  1891.             updater.console.println("=== StReadStart ===");
  1892.             sm.response = null;
  1893.  
  1894.             if (sm.cachedScriptModDate) {
  1895.               updater.console.println(" calls updater.net.urlGetAsync() using if-mod-since");
  1896.               sm.urlMon = updater.net.urlGetAsync(scriptURL, sm.cachedScriptModDate.toUTCString());
  1897.               }
  1898.             else {
  1899.               updater.console.println(" calls updater.net.urlGetAsync()");
  1900.               sm.urlMon = updater.net.urlGetAsync(scriptURL);
  1901.               }
  1902.             sm.state = sm.enumStates.StProcessUI;
  1903.             }
  1904.           catch (e) {
  1905.             updater.console.println("Exception in StReadStart" + e);
  1906.             sm.exception = "URLGetException";
  1907.             sm.state = sm.enumStates.StException;
  1908.             }
  1909.           break;
  1910.  
  1911.         case st_enum.StProcessUI :
  1912.           try {
  1913.             updater.console.println("=== StProcessUI ===");
  1914.             // updater.app.processDialogEvent();
  1915.             sm.state = sm.enumStates.StUIWait; 
  1916.             }
  1917.           catch (e) {
  1918.               updater.console.println("Exception in StPocessUI: " + e);
  1919.               sm.exception = e;
  1920.               sm.state = sm.StException;            
  1921.             }
  1922.           break;
  1923.  
  1924.         case st_enum.StUIWait :
  1925.           try {
  1926.             updater.console.println("=== StUIWait ===");
  1927.             sm.uiCancelled = updater.app.isProgressDialogCancelled()
  1928.             sm.state = sm.enumStates.StReadWait; 
  1929.             }
  1930.           catch (e) {
  1931.               updater.console.println("Exception in StUIWait: " + e);
  1932.               sm.exception = e;
  1933.               sm.state = sm.StException;            
  1934.             }
  1935.           break;
  1936.               
  1937.         case st_enum.StReadWait :
  1938.           try {
  1939.             updater.console.println("=== StReadWait ===");
  1940.  
  1941.             if (sm.uiCancelled) {
  1942.               sm.urlMon.cancel();
  1943.               sm.exception = "DownloadCancelled";
  1944.               sm.state = sm.enumStates.StException;
  1945.               break;
  1946.               }
  1947.  
  1948.             if (sm.urlMon.done) {
  1949.               sm.state = st_enum.StReadDone;
  1950.               break;
  1951.               }
  1952.  
  1953.             sm.urlMon.wait();
  1954.  
  1955.             sm.state = st_enum.StProcessUI;
  1956.             }
  1957.           catch (e) {
  1958.             updater.console.println("Exception in StReadWait" + e);
  1959.             sm.exception = e;
  1960.             sm.state = sm.enumStates.StException;
  1961.             }
  1962.           break;
  1963.  
  1964.         case st_enum.StReadDone:
  1965.           try {
  1966.             updater.console.println("=== StReadDone ===");
  1967.  
  1968.             // should check again if ui is cancelled due to late click
  1969.             // latching
  1970.             if (updater.app.isProgressDialogCancelled()) {
  1971.               sm.exception = "DownloadCancelled";
  1972.               sm.state = sm.enumStates.StException;
  1973.               break;
  1974.               }
  1975.  
  1976.             if (! updater.MasterScript.PropertyIsDefined(sm, "scriptObjs")
  1977.                 || (sm.scriptObjs.constructor != Array) ) {
  1978.               sm.scriptObjs = new Array();
  1979.               }
  1980.  
  1981.             var idx = sm.scriptArgIdx;
  1982.  
  1983.             // acrobat can raise in urlMon.response if the download scripts
  1984.             // not signed correctly
  1985.             sm.scriptObjs[idx] = 
  1986.                 updater.MasterScript.GetAndCacheScriptObjFromResp(sm.cachedScriptObj, 
  1987.                    sm.urlMon.response, serializationRoot, scriptCacheName);
  1988.  
  1989.             // mount call point
  1990.             if (!dontMount) {
  1991.               updater[callPoint] = sm.scriptObjs[idx];
  1992.               }
  1993.  
  1994.             // initialize script obj
  1995.             if (updater.MasterScript.PropertyIsDefined(updater[callPoint], 
  1996.                                                        "Initialize")
  1997.                 &&
  1998.                 updater[callPoint]["Initialize"].constructor == Function) {
  1999.               updater[callPoint]["Initialize"]();
  2000.               }
  2001.  
  2002.             // done when all script in loadScriptArgs is iterated 
  2003.             sm.scriptArgIdx++;
  2004.             if (sm.scriptArgIdx < loadScriptArgs.length) {
  2005.               sm.state = st_enum.StInit;
  2006.             }
  2007.             else {
  2008.               if (closeUI) {
  2009.                 updater.app.hideProgressDialog();
  2010.                 }
  2011.               sm.state = st_enum.StFinished;
  2012.               }
  2013.             }
  2014.           catch (e) {
  2015.             updater.console.println("Exception in StReadDone : " + e);
  2016.             sm.exception = e;
  2017.             sm.state = sm.enumStates.StException;
  2018.             }
  2019.           break;
  2020.  
  2021.         case st_enum.StException:
  2022.           updater.console.println("=== StException ===");
  2023.           // always closes UI when exception happens
  2024.           updater.app.hideProgressDialog();
  2025.  
  2026.           var e = sm.exception;
  2027.           updater.console.println("Exception in " + sm.name + ": " + e);
  2028.  
  2029.           if (e == "URLGetException" || e == "URLContentNotFound" || e == "ServerError") {
  2030.             // These errors are probably network or server related.  don't
  2031.             // even need to bother user with the error.  just inform them no
  2032.             // update is available at this time
  2033.             var title = updater.app.getUpdaterString("uisJSNoUpdtAvailTitle");
  2034.             var errMsg = updater.app.getUpdaterString("uisJSNoUpdtAvailAtThisTimeText");
  2035.  
  2036.             if (! suppressUI) 
  2037.               updater.app.alert({nIcon:3, nType:0, cTitle:title, cMsg:errMsg});
  2038.             }
  2039.           else if (e == "NoDateHeader" || e == "BadData") {
  2040.             // probably should not pop dialog here since these are internal
  2041.             // errors from downloadAndCacheScript
  2042.             var title = updater.app.getUpdaterString("bsJSNoNetConnectTitle");
  2043.             var errMsg = updater.app.getUpdaterString("bsJSInternalErrorText");
  2044.             
  2045.             if (! suppressUI)
  2046.               updater.app.alert({nIcon:0, nType:0, cTitle:title, cMsg:errMsg});
  2047.             }
  2048.           else if (e == "DownloadCancelled" ) {
  2049.             updater.MasterScript.assert(false, "DownloadCancelled");
  2050.             updater.console.println("DownloadCancelled");
  2051.             // siliently swollow the exception if user cancelled out
  2052.             }
  2053.  
  2054.           sm.exception = "LoadScriptException";
  2055.           sm.state = st_enum.StFinished;
  2056.           break;
  2057.  
  2058.         case st_enum.StFinished:
  2059.           try {
  2060.             updater.console.println("=== StFinished ===");
  2061.             
  2062.             // should check again if ui is cancelled due to late click
  2063.             // latching
  2064.             if (!sm.uiCancelled && updater.app.isProgressDialogCancelled()) {
  2065.               updater.MasterScript.assert(false, "DownloadCancelled");
  2066.               updater.console.println("DownloadCancelled");
  2067.               sm.exception = "LoadScriptException";
  2068.               sm.state = sm.enumStates.StException;
  2069.               }
  2070.  
  2071.             updater.app.clearInterval(sm.handle);
  2072.             sm.done = true;
  2073.             updater.gStateMachineLock = false;
  2074.           
  2075.             // call resume proc when done
  2076.             updater.MasterScript.assert(sm.resumeProc.constructor == Function, "resumeProc NOT a function");
  2077.             if (sm.resumeProc.constructor == Function) {
  2078.               sm.resumeProc(sm);
  2079.               }
  2080.             else {
  2081.               updater.console.println("sm.resumeProc not a function.  skip calling");
  2082.               }
  2083.             }
  2084.           catch (e) {
  2085.             updater.console.println("Exception in StFinished" + e);
  2086.             // close the UI 
  2087.             updater.app.hideProgressDialog();
  2088.             }
  2089.           break;
  2090.           
  2091.         default :
  2092.           updater.MasterScript.assert(false, "Shoule NOT reach default case - " + sm.name);
  2093.           throw "CannotHappen";
  2094.           break;
  2095.           }
  2096.         }
  2097.       catch (e) {
  2098.         sm.exception = e;
  2099.  
  2100.         updater.app.clearInterval(sm.handle);
  2101.         sm.done = true;
  2102.         updater.gStateMachineLock = false;
  2103.  
  2104.         updater.console.println("Exception in SBgDlProcessState: " + e);
  2105.       }
  2106.     },
  2107.  
  2108.     // 
  2109.     // Updater Script loading machinism
  2110.     // 
  2111.     // MasterScript: assumed always available (from bootstrap.js).  it
  2112.     // exports common functions and system functions to all other scripts.
  2113.     // It ONLY knows how to load DataScript.js.  Once DataScript is loaded,
  2114.     // MasterScript inquires DataScript about what other scripts DataScript
  2115.     // needs by calling DataScript.GetScriptDependencyList() and load all the
  2116.     // required scripts.  After each script is loaded, its Initialize()
  2117.     // function will be called if exists.
  2118.     //
  2119.     // DataScript: loaded only by MasterScript.  It has three piece of
  2120.     // information:
  2121.     //
  2122.     // 1) the available component data structure.  it contains all available
  2123.     // component for a given acrobat product configuration.
  2124.     //
  2125.     // 2) messages to be shown by the notification dialog
  2126.     //
  2127.     // 3) A function that returns a script depency list.  This allow future
  2128.     // expandability.  it initially contains only CodeScript and UIScript.
  2129.     //
  2130.     // DataScript Initialize() will have to check if the system has correct
  2131.     // version of MasterScript.  If not, it would call
  2132.     // LoadAndCacheScriptAsync() to get a new MasterScript.  A viewer restart
  2133.     // is required if new MasterScript is loaded.
  2134.     // 
  2135.     // CodeScript: Contains all procedures for doing Auto Update, Manual
  2136.     // Update, FincComponent, etc.
  2137.     //
  2138.     // UIScript: Contains all UI elements for Updater.
  2139.     //
  2140.     // Since MasterScript knows only DataScript, call-chaining is used so
  2141.     // that arbitrary scripts (potentially new scripts) can be used to
  2142.     // implement/replace Updater's functionality.  It works like this:
  2143.     // 
  2144.     // DataScript and the script contains the implementation of Updater's
  2145.     // functionality contains a common entry point, aptly named entryPoint().
  2146.     // it is called with an {} with "func", and "args" memebers.  DataScript
  2147.     // has the right to vector off the requests to the implementation script
  2148.     // (CodeScript) by simply calling entryPoint() with pass the arg along.
  2149.     // MasterScript.AutoUpdate() --> DataScript.entryPoint(arg)
  2150.     // --> CodeScript.entryPoint(arg) --> CodeScript.AutoUpdate(udArgs)
  2151.     // where arg is {func:AutoUpdate, arg:{udArgs}}
  2152.     // udArags is an {}
  2153.     //
  2154.     
  2155.     
  2156.     //
  2157.     // this is a non blocking call.  if suppressUI is true, no UI is shown by
  2158.     // default, the UI is not closed when operation is done unless closeUI is
  2159.     // true.  UI is always closed when exception happens
  2160.     //
  2161.     // loadScriptArgs is an array of elements:
  2162.     // {
  2163.     //   "scriptURL" : this.getDSURL(),
  2164.     //   "serializationRoot" : updater.store.perUser,
  2165.     //   "scriptCacheName" : "cachedDataScript",
  2166.     //   "callPoint" : "DataScript"
  2167.     //   "temp" : false
  2168.     // }
  2169.     //
  2170.     LoadAndCacheScriptAsync: function(loadScriptArgs,
  2171.                                       resumeProc, resumeArgs,
  2172.                                       suppressUI, closeUI)
  2173.     {
  2174.       var idleProc =  "updater.MasterScript.SBgDlProcessState()";
  2175.       
  2176.       var idleArgs = { "loadScriptArgs" : loadScriptArgs,
  2177.                        "suppressUI" : suppressUI,
  2178.                        "closeUI" : closeUI };
  2179.                       
  2180.       this.SStartStateMachine(idleProc, idleArgs,
  2181.                               resumeProc, resumeArgs, 
  2182.                               "SBgDlProcessState", this.SBgDlStates);
  2183.       return this.SStartStateMachine;
  2184.     },
  2185.  
  2186.     LoadScriptDepFinishProc: function(sm)
  2187.     {
  2188.       try {
  2189.         updater.console.println("LoadScriptDepFinishProc()"); 
  2190.         // something wrong in state machine, raise it
  2191.         if (sm.exception) { throw sm.exception };
  2192.  
  2193.         updater.MasterScript.assert(sm.resumeArgs["dsCallerResumeProc"], "dsCallerResumeProc undefined! ");
  2194.         
  2195.         updater.app.hideProgressDialog();
  2196.  
  2197.         var func = sm.resumeArgs["dsCallerResumeProc"];
  2198.         var args = sm.resumeArgs["dsCallerResumeArgs"];
  2199.         if (func.constructor == Function) {
  2200.           func(args);
  2201.           }
  2202.         }
  2203.       catch (e) {
  2204.         updater.console.println("Exception in LoadScriptDepFinishProc: " + e);
  2205.         }
  2206.     },
  2207.  
  2208.     LoadDataScriptFinishProc: function(sm)
  2209.     {
  2210.       try {
  2211.         updater.console.println("LoadDataScriptFinishProc()"); 
  2212.  
  2213.         // something wrong in state machine, raise it
  2214.         if (sm.exception) { throw sm.exception };
  2215.  
  2216.         var depScriptsArgs = updater.DataScript.GetScriptDependency();
  2217.  
  2218.         // updater.MasterScript.DumpObject(depScriptsArgs,"depScriptsArgs", true);
  2219.  
  2220.         updater.MasterScript.assert(depScriptsArgs.constructor == Array);
  2221.  
  2222.         var suppressUI = sm.resumeArgs["dsCallerSuppressUI"];
  2223.         var closeUI = sm.resumeArgs["dsCallerCloseUI"];
  2224.  
  2225.         updater.MasterScript.LoadAndCacheScriptAsync(depScriptsArgs, 
  2226.                                                      updater.MasterScript.LoadScriptDepFinishProc,
  2227.                                                      sm.resumeArgs,
  2228.                                                      suppressUI, closeUI);
  2229.         }
  2230.       catch (e) {
  2231.         updater.console.println("Exception in LoadDataScriptFinishProc: " + e);
  2232.         }
  2233.     },
  2234.     
  2235.     LoadDataScriptAsync: function(resumeProc, resumeArgs, 
  2236.                                   suppressUI, closeUI)
  2237.     {
  2238.       var loadScriptArgs = new Array();
  2239.  
  2240.       var dsLoadArgs = {
  2241.         "scriptURL" : this.getDSURL(),
  2242.         "serializationRoot" : updater.store.perUser,
  2243.         "scriptCacheName" : "cachedDataScript",
  2244.         "callPoint" : "DataScript"
  2245.         };
  2246.       
  2247.       loadScriptArgs[0] = dsLoadArgs;
  2248.       
  2249.       var dsFinishArg = {"dsCallerResumeProc": resumeProc,
  2250.                          "dsCallerResumeArgs" : resumeArgs,
  2251.                          "dsCallerSuppressUI" : suppressUI,
  2252.                          "dsCallerCloseUI" : closeUI};
  2253.  
  2254.       // before running resumeProc and resumeArgs, will call
  2255.       // LoadDataScriptFinishProc it load up all scripts DataScript requires
  2256.       this.LoadAndCacheScriptAsync(loadScriptArgs,
  2257.                                    this.LoadDataScriptFinishProc, dsFinishArg,
  2258.                                    suppressUI, closeUI);
  2259.     },
  2260.  
  2261.  
  2262.     //
  2263.     // Manual Update Procs
  2264.     //
  2265.     // this is called when DataScript.entryPoint() is done
  2266.     ManualUpdateCallBackProc: function(args)
  2267.     {
  2268.       try {
  2269.         updater.MasterScript.saveState();  // can raise 
  2270.       }
  2271.       catch (e) {
  2272.         updater.console.println("Exception in ManualUpdateCallBackProc: " + e);
  2273.       }
  2274.     },
  2275.  
  2276.     // this is called when DataScript has been downloaded
  2277.     ManualUpdateFinishProc: function(args)
  2278.     {
  2279.       // call datascript main entry point
  2280.       try {
  2281.         updater.console.println("ManualUpdateFinishProc()"); 
  2282.  
  2283.         args.callBack = updater.MasterScript.ManualUpdateCallBackProc;
  2284.         args.callBackArgs = null;
  2285.         updater.DataScript.entryPoint(args);
  2286.       }
  2287.       catch (e) {
  2288.         updater.console.println("Exception in ManualUpdateFinishProc: " + e);
  2289.       }
  2290.     },
  2291.  
  2292.     ManualUpdateAsync: function()
  2293.     {
  2294.       try {
  2295.         updater.console.println("ManualUpdateAsync()"); 
  2296.         if ( ! this.init(false) ) return;
  2297.  
  2298.         this.loadState();
  2299.  
  2300.         updater.isAutoUpdate = false;
  2301.         updater.useSyncRead = false;
  2302.         var finishProcArgs = {func:"doUpdate", 
  2303.                               args:{isAutoUpdate:false}};
  2304.         this.LoadDataScriptAsync(this.ManualUpdateFinishProc, finishProcArgs);
  2305.         }
  2306.       catch (e) {
  2307.           updater.console.println("Exception in ManualUpdateAsync: " + e);
  2308.           return false;
  2309.       }
  2310.     },
  2311.  
  2312.  
  2313.     //
  2314.     // AutoUpdate and Check DLM Procs
  2315.     // 
  2316.  
  2317.     // this is called when DataScript.entryPoint() is done
  2318.     AutoUpdateCallBackProc: function(args)
  2319.     {
  2320.       try {
  2321.         updater.MasterScript.advanceNextCheckDate();
  2322.         updater.MasterScript.popNotifications();
  2323.         updater.MasterScript.saveState();  // can raise 
  2324.       }
  2325.       catch (e) {
  2326.         updater.console.println("Exception in AutoUpdateCallBackProc: " + e);
  2327.       }
  2328.     },
  2329.  
  2330.     // this is called when DataScript has been downloaded
  2331.     AutoUpdateFinishProc: function(args)
  2332.     {
  2333.       // call datascript main entry point
  2334.       try {
  2335.         updater.console.println("AutoUpdateFinishProc()"); 
  2336.  
  2337.         args.callBack = updater.MasterScript.AutoUpdateCallBackProc;
  2338.         args.callBackArgs = null;
  2339.         updater.DataScript.entryPoint(args);
  2340.       }
  2341.       catch (e) {
  2342.         updater.console.println("Exception in AutoUpdateFinishProc: " + e);
  2343.       }
  2344.     },
  2345.  
  2346.  
  2347.     CheckDLMStateFinishProc: function(args)
  2348.     {
  2349.       // call datascript main entry point
  2350.       try {
  2351.         updater.console.println("CheckDLMStateFinishProc()");
  2352.  
  2353.         updater.DataScript.entryPoint(args);
  2354.         }
  2355.       catch (e) {
  2356.         updater.console.println("Exception in CheckDLMStateFinishProc: " + e);
  2357.         }
  2358.     },
  2359.  
  2360.     AutoUpdateAsync: function()
  2361.     {
  2362.       try {
  2363.         updater.console.println("AutoUpdateAsync()"); 
  2364.  
  2365.         if ( ! this.init(true) ) return;
  2366.  
  2367.         // do a quick check before using CodeScript's CheckDLMState() which
  2368.         // has dialogs.
  2369.         var dlmState = updater.dlm.getState();
  2370.         updater.console.println("  updater.dlm.getState() returns " + dlmState);
  2371.         // DLM not running.  rdy to accept transaction
  2372.         // quickly return
  2373.         if (dlmState != 0) { 
  2374.           // DLM has pending stuff
  2375.           // ok.  now we must do some UI since there are pending updates
  2376.           // calls into CodeScript's CheckDLMState()
  2377.           
  2378.           if (! updater.MasterScript.checkNetConnection(true) ) {
  2379.             // if no net, try if all scripts are cached already.
  2380.             var hasAllScripts = updater.MasterScript.getAllScriptsFromStore();
  2381.             if (hasAllScripts) {
  2382.               updater.DataScript.entryPoint({func:"CheckDLMState", args:{}}); 
  2383.               }
  2384.             }
  2385.           else {
  2386.             // has net connection
  2387.             var finishProcArgs = {func:"CheckDLMState", 
  2388.                                   args:{}};
  2389.             this.LoadDataScriptAsync(this.CheckDLMStateFinishProc, finishProcArgs, true);
  2390.             }
  2391.           return;
  2392.           }
  2393.         else {
  2394.           // continue AutoUpdate
  2395.           this.loadState();
  2396.  
  2397.           // check if pref is set the monthly
  2398.           // monthly: 1
  2399.           // manually: 0
  2400.           var freq = updater.app.getUpdateFrequency();
  2401.           updater.console.println("  freq = " + freq);
  2402.  
  2403.           // do auto update when it is time to AND freq is monthly
  2404.           if ( (freq == 1) &&  this.isTimeToUpdate() ) {
  2405.             // silently returns if autoupdate and no net
  2406.             if (! updater.MasterScript.checkNetConnection(true) ) {
  2407.               return false;
  2408.               }
  2409.             
  2410.             updater.isAutoUpdate = true;
  2411.             updater.useSyncRead = true;
  2412.             
  2413.             var finishProcArgs = {func:"doUpdate", 
  2414.                                   args:{isAutoUpdate:true}};
  2415.             this.LoadDataScriptAsync(this.AutoUpdateFinishProc, finishProcArgs, true);
  2416.             }
  2417.           else {
  2418.             // pop new notifications. calls only finish auto-update check, not
  2419.             // manual check
  2420.             this.popNotifications();
  2421.             this.saveState();  // can raise
  2422.             }
  2423.           }
  2424.         }
  2425.       catch (e) {
  2426.         updater.console.println("Exception in AutoUpdateAsync: " + e);
  2427.         return false;
  2428.         }
  2429.     },
  2430.  
  2431.  
  2432.     //
  2433.     // FindComponent Procs
  2434.     // 
  2435.     // this is called when DataScript.entryPoint() is done
  2436.     FindComponentCallBackProc: function(args)
  2437.     {
  2438.       try {
  2439.         var ret = args["returnVal"];
  2440.         updater.console.println("ComponentFound = " + ret); 
  2441.         updater.MasterScript.saveState();  // can raise 
  2442.       }
  2443.       catch (e) {
  2444.         updater.console.println("Exception in FindComponentCallBackProc: " + e);
  2445.       }
  2446.     },
  2447.  
  2448.     // this is called when DataScript has been downloaded
  2449.     FindComponentFinishProc: function(args)
  2450.     {
  2451.       // call datascript main entry point
  2452.       try {
  2453.         updater.console.println("FindComponentFinishProc()"); 
  2454.  
  2455.         args.callBack = updater.MasterScript.FindComponentCallBackProc;
  2456.         args.callBackArgs = null;
  2457.         updater.DataScript.entryPoint(args);
  2458.       }
  2459.       catch (e) {
  2460.         updater.console.println("Exception in FindComponentFinishProc: " + e);
  2461.       }
  2462.     },
  2463.  
  2464.     FindComponentAsync: function(type, name, desc, ver, params)
  2465.     {
  2466.       try {
  2467.         updater.console.println("FindComponentAsync()"); 
  2468.  
  2469.         if ( ! this.init() ) return;
  2470.  
  2471.         this.loadState();
  2472.  
  2473.         var hasNet = updater.net.isConnected();
  2474.         var wellKnown = false;
  2475.  
  2476.         if ( !desc || desc.length == 0 ) {
  2477.           // no desc given by caller.  try lookup well known component
  2478.           // description
  2479.           var knownDesc = this.lookUpWellKnownCompDesc(type, name);
  2480.           if (knownDesc && knownDesc.length > 0) {
  2481.             wellKnown = true;
  2482.             desc = knownDesc;
  2483.             }
  2484.           else {
  2485.             wellKnown = false;
  2486.             desc = type + "/" + name;
  2487.             if (ver) desc = desc + ":" + ver;
  2488.             }
  2489.           }
  2490.  
  2491.         updater.console.println("  wellKnown = " + wellKnown);
  2492.         updater.console.println("  desc      = " + desc);
  2493.         // if no net, prompt user if connecting to net is ok
  2494.         if (! hasNet) {
  2495.           var cont;
  2496.           if (wellKnown) {
  2497.             cont = this.showMissingCompDialog(desc);
  2498.             }
  2499.           else {
  2500.             cont = this.showMissingCompDialog();
  2501.             }
  2502.           // no = 3,  yes =4
  2503.           if (cont == 3) return false;
  2504.           }
  2505.         
  2506.         // user wants to continue.  forward request to CodeScript via DataScript
  2507.         // download the datascript (may need to connect to net)
  2508.  
  2509.  
  2510.         var finishProcArgs = {func:"findComponent", 
  2511.                               args:{type:type, name:name, desc:desc, ver:ver, params:params}};
  2512.         this.LoadDataScriptAsync(this.FindComponentFinishProc, finishProcArgs);
  2513.         return true;
  2514.         }
  2515.       catch (e) {
  2516.           updater.console.println("Exception in FindComponentAsync: " + e);
  2517.           return false;
  2518.       }
  2519.     },
  2520.  
  2521.  
  2522.  
  2523.     __ENDER__:"END"
  2524. };
  2525.  
  2526. ScriptObj;
  2527. //
  2528. // StartUp.js
  2529. // 
  2530. // Edit History:
  2531. // Danny Siu: Fri Apr 18 01:35:10 2003
  2532. // End History
  2533. //
  2534. // [SHOULD REMOVE ALL THE COMMENTS FROM PRODUCTION!!!]
  2535. // 
  2536. // the sole purpose of bootstrap script is to load up the masterscript and
  2537. // make sure it exists in Updater JS runtime (ie: defines
  2538. // updater.MasterScript).  it must also define a updater.scriptRootURL which
  2539. // can be used to defer the location of MasterScript on the server.
  2540. //
  2541. // during developement, the MasterScript is always loaded from a server by
  2542. // doing urlGet().  For release, there should be a presisted MasterScript in
  2543. // user's dir and the bootstrap script should load up the presist file and
  2544. // bring the cached MasterScript back to life.
  2545. //
  2546. // 2002-12-11 Updates: 
  2547. // 
  2548. // Here is how MasterScript would be loaded up: 
  2549. // 
  2550. // 1) First check if an presisted version in updater.store is available.  If
  2551. // so, check its version againt updater.MasterScript( if it is even defined
  2552. // in the runtime probably because of bootstrap.js evaluation)
  2553. //
  2554. // Then set updater.MasterScript to the newer version.  This allow us to
  2555. // update and override MasterScript later on.
  2556. //
  2557. // 2) if NOT, use darn simple urlGet() to fetch it from
  2558. // updater.masterScriptURL the newly fetched script will be presisted so that
  2559. // it doesn't need to be refetch next time
  2560. // 
  2561. //
  2562. // updater.bootStrapped is a globle which C++ code can check if bootstrapping
  2563. // has happened.  it is for optimization so that bootstrip.js will only be
  2564. // opened and eval'ed once per app launch.
  2565. //
  2566. // updater.scriptRootURL is the base of where all scripts will live on server
  2567. //
  2568.  
  2569. // The stable set of scripts updated once or twice a week for QE and Dev
  2570. // This is the default location for Updater scripts within Adobe
  2571. // updater.scriptRootURL = "http://mcmug.corp.adobe.com/~dsiu/NewportUpdater/js/";
  2572.  
  2573. // Lastest and greatest scripts for development and limited QE testing
  2574. // Uncomment the following line if you want to try the latest scripts
  2575. // updater.scriptRootURL = "http://mcmug.corp.adobe.com/~dsiu/NewportUpdater/js_dev/";
  2576.  
  2577. // For my own development using local web server
  2578. // do not uncomment the following unless you know what you are doing 
  2579. // updater.scriptRootURL = "http://127.0.0.1/NewportUpdater/js/";
  2580.  
  2581. // For Beta3 deployment
  2582. updater.scriptRootURL = "http://update.adobe.com/pub/adobe/acrobat/js/6.x/";
  2583.  
  2584. // updater.bootStrapped = false;
  2585.  
  2586.  
  2587. if (! updater.bootStrapped) {
  2588.  
  2589.   try {
  2590.     updater.console.println("===== Loading bootstrap.js =====");
  2591.  
  2592.     // Since MasterScript WILL be prepended this file to form bootstrap.js, need
  2593.     // to check if ScriptObj exists and and pick it up as MasterScript
  2594.     if (typeof(ScriptObj) != "undefined") {
  2595.       updater.console.println("  picked up default MasterScript from bootstrap.js");
  2596.       updater.MasterScript = ScriptObj;
  2597.     }
  2598.  
  2599.     // overrideable scriptRootURL by Pref
  2600.     // updater.avpref can raise if the pref section/key not defined
  2601.     try {
  2602.       updater.scriptRootURL = updater.avpref.get("Updater", 
  2603.                                                  "ScriptRootURL", 
  2604.                                                  updater.avpref.type["String"], 
  2605.                                                  updater.scriptRootURL);
  2606.       updater.console.println("  overriding scriptRootURL from pref");
  2607.     } catch (e) {}  // safely ignore the raise by avpref 
  2608.  
  2609.     updater.console.println("  updater.scriptRootURL = " + updater.scriptRootURL);
  2610.  
  2611.     // first check if there is a presisted version (the following code has
  2612.     // CANNOT assume existence of MasterScripts and its friends of utilities
  2613.     // functions)
  2614.  
  2615.     try {
  2616.       updater.store.load();
  2617.       }
  2618.     catch (e) {
  2619.       updater.console.println("Exception in trying to do updater.store.load(): " + e);
  2620.       updater.console.println("  --> skip loading store");
  2621.       }
  2622.  
  2623.     var cachedMSVersion;
  2624.     var cachedMSName = "cachedMasterScript";
  2625.     cachedMSName = cachedMSName + "_" + updater.app.viewerType + "_" + updater.app.language;
  2626.     var curRunTimeMSVersion;
  2627.  
  2628.     var gotMasterScript = false;
  2629.  
  2630.     
  2631.     // version checking 
  2632.  
  2633.     // finding out cached MasterScript version
  2634.     if ( typeof(updater.store.perUser[cachedMSName]) != "undefined" &&
  2635.          typeof(updater.store.perUser[cachedMSName]["scriptObj"]) != "undefined" )
  2636.       {
  2637.       cachedMSVersion = updater.store.perUser[cachedMSName].scriptObj.version + 0.0;
  2638.       updater.console.println(" checking cachedMSVersion = " + cachedMSVersion);
  2639.       }
  2640.     else {
  2641.       cachedMSVersion = 0.0;
  2642.       }
  2643.  
  2644.     // finding out current MasterScript version
  2645.     if ( (typeof(updater["MasterScript"]) != "undefined" ) &&
  2646.          (typeof(updater.MasterScript["version"]) != "undefined") ) 
  2647.       {
  2648.       curRunTimeMSVersion = updater.MasterScript.version + 0.0;
  2649.       updater.console.println(" checking curRunTimeMSVersion = " + curRunTimeMSVersion);
  2650.       }
  2651.     else {
  2652.       curRunTimeMSVersion = 0.0;
  2653.       }
  2654.  
  2655.     if ( (curRunTimeMSVersion != 0) && (curRunTimeMSVersion > cachedMSVersion) ) {
  2656.       updater.console.println("--> Using MasterScript from current runtime.  version = " + curRunTimeMSVersion);
  2657.       gotMasterScript = true;
  2658.       }
  2659.  
  2660.     // MUST use >= to compare cached verion with the current one in runtime
  2661.     // since current one in runtime may well be the cached one when bootstrip
  2662.     // is eval the second time
  2663.     if ( !gotMasterScript &&
  2664.          (cachedMSVersion != 0) && (cachedMSVersion >= curRunTimeMSVersion) ) {
  2665.       updater.MasterScript = updater.store.perUser[cachedMSName].scriptObj;
  2666.       updater.console.println("--> Using MasterScript from cache.  version = " + cachedMSVersion);
  2667.       gotMasterScript = true;
  2668.       }
  2669.  
  2670.     if (!gotMasterScript) {
  2671.       // no existing MasterScript....do a urlGet();
  2672.       // first check if there is net connection
  2673.       var hasNet; 
  2674.       if ( typeof(updater.net["isConnected"]) != "undefined") {
  2675.         hasNet = updater.net.isConnected();
  2676.         }
  2677.       else {
  2678.         hasNet = updater.dlm.hasNetAccess();
  2679.         }
  2680.       
  2681.       if (! hasNet) {
  2682.         // should use UIScript's showErrorDialog() when UIScript is presisted.
  2683.         // for now just do app.alert.
  2684.         var title = updater.app.getUpdaterString("bsJSNoNetConnectTitle");
  2685.         var errMsg = updater.app.getUpdaterString("bsJSNoNetConnectText");
  2686.         updater.app.alert({nIcon:0, nType:0, cTitle:title, cMsg:errMsg});
  2687.         }
  2688.       else {
  2689.         updater.console.println("  fetching MasterScript with urlGet()");
  2690.  
  2691.         // should add prod config into creating the URL later
  2692.         var masterScriptURL = updater.scriptRootURL + "MasterScript.js";
  2693.  
  2694.         var resp = updater.net.urlGet(masterScriptURL);
  2695.  
  2696.         updater.console.println("  eval MasterScript");
  2697.         var newScriptObj = eval( resp.Content );
  2698.         updater.console.println("  eval MasterScript doone");
  2699.         if ( newScriptObj == null ) {
  2700.           updater.console.println("  something wrong while eval resp.Content.  throws!");
  2701.           throw "badData";
  2702.           }
  2703.         updater.MasterScript = newScriptObj;
  2704.         
  2705.         updater.console.println("  saving MasterScript");
  2706.         // can null be used for cachedDate?
  2707.         updater.store.perUser[cachedMSName] = { cachedDate : null,
  2708.                                                 scriptObj : newScriptObj };
  2709.  
  2710.         // save user store
  2711.         try {
  2712.           updater.store.save();
  2713.           }
  2714.         catch (e) {
  2715.           updater.console.println("Exception in trying to updater.store.save(): " + e);
  2716.           throw new Error("SaveStateException");
  2717.           }
  2718.         
  2719.         gotMasterScript = true;
  2720.         }
  2721.       }
  2722.  
  2723.     updater.bootStrapped = gotMasterScript;
  2724.  
  2725. //     if (gotMasterScript &&
  2726. //         typeof(updater.MasterScript["InstallPrefPanel"] != "undefined") ) {
  2727. //       updater.console.println("  installing PrefPanel");
  2728. //       updater.MasterScript.InstallPrefPanel();
  2729. //       }
  2730.  
  2731.     updater.console.println("===== bootstrap.js done =====");
  2732.     }
  2733.   catch (e) {
  2734.     updater.console.println("  Exception during bootstrap - " + e);
  2735.     }
  2736. }
  2737. else {
  2738.   updater.console.println("===== bootstrap.js already loaded =====");
  2739. }
  2740.  
  2741.  
  2742.